diff --git a/memcheck/docs/mc-manual.xml b/memcheck/docs/mc-manual.xml index ea1d36363..0a0a0780d 100644 --- a/memcheck/docs/mc-manual.xml +++ b/memcheck/docs/mc-manual.xml @@ -46,9 +46,6 @@ Memcheck can detect the following problems: memcpy() and related functions - - Some misuses of the POSIX pthreads API - @@ -159,19 +156,25 @@ Memcheck can detect the following problems: --partial-loads-ok=yes - [default] - --partial-loads-ok=no - Controls how Memcheck handles word (4-byte) loads from + + --partial-loads-ok=no[default] + + Controls how Memcheck handles word-sized, word-aligned loads from addresses for which some bytes are addressible and others are - not. When yes (the - default), such loads do not elicit an address error. + not. When yes, + such loads do not elicit an address error. Instead, the loaded V bytes corresponding to the illegal - addresses indicate undefined, and those corresponding to + addresses indicate Undefined, and those corresponding to legal addresses are loaded from shadow memory, as usual. - When no, loads from - partially invalid addresses are treated the same as loads - from completely invalid addresses: an illegal-address error + When no(the default), + loads from partially invalid addresses are treated the same as + loads from completely invalid addresses: an illegal-address error is issued, and the resulting V bytes indicate valid data. + Note that code that behaves in this way is in violation of + the the ISO C/C++ standards, and should be considered broken. + If at all possible, such code should be fixed. This flag should + be used only as a last resort. + diff --git a/memcheck/mac_shared.c b/memcheck/mac_shared.c index fb6b01a6c..bd303be2d 100644 --- a/memcheck/mac_shared.c +++ b/memcheck/mac_shared.c @@ -58,7 +58,7 @@ /*--- Command line options ---*/ /*------------------------------------------------------------*/ -Bool MAC_(clo_partial_loads_ok) = True; +Bool MAC_(clo_partial_loads_ok) = False; Int MAC_(clo_freelist_vol) = 5000000; LeakCheckMode MAC_(clo_leak_check) = LC_Summary; VgRes MAC_(clo_leak_resolution) = Vg_LowRes; @@ -100,7 +100,7 @@ void MAC_(print_common_usage)(void) " --leak-check=no|summary|full search for memory leaks at exit? [summary]\n" " --leak-resolution=low|med|high how much bt merging in leak check [low]\n" " --show-reachable=no|yes show reachable blocks in leak check? [no]\n" -" --partial-loads-ok=no|yes too hard to explain here; see manual [yes]\n" +" --partial-loads-ok=no|yes too hard to explain here; see manual [no]\n" " --freelist-vol= volume of freed blocks queue [5000000]\n" " --workaround-gcc296-bugs=no|yes self explanatory [no]\n" ); diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 96ce84d00..ba8183960 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -417,7 +417,7 @@ ULong mc_LOADVn_slow ( Addr a, SizeT szB, Bool bigendian ) SizeT i = szB-1; SizeT n_addrs_bad = 0; Addr ai; - Bool aok; + Bool aok, partial_load_exemption_applies; UWord abit, vbyte; PROF_EVENT(30, "mc_LOADVn_slow"); @@ -436,7 +436,25 @@ ULong mc_LOADVn_slow ( Addr a, SizeT szB, Bool bigendian ) i--; } - if (n_addrs_bad > 0) + /* This is a hack which avoids producing errors for code which + insists in stepping along byte strings in aligned word-sized + chunks, and there is a partially defined word at the end. (eg, + optimised strlen). Such code is basically broken at least WRT + semantics of ANSI C, but sometimes users don't have the option + to fix it, and so this option is provided. Note it is now + defaulted to not-engaged. + + A load from a partially-addressible place is allowed if: + - the command-line flag is set + - it's a word-sized, word-aligned load + - at least one of the addresses in the word *is* valid + */ + partial_load_exemption_applies + = MAC_(clo_partial_loads_ok) && szB == VG_WORDSIZE + && VG_IS_WORD_ALIGNED(a) + && n_addrs_bad < VG_WORDSIZE; + + if (n_addrs_bad > 0 && !partial_load_exemption_applies) MAC_(record_address_error)( VG_(get_running_tid)(), a, szB, False ); return vw;