diff --git a/memcheck/docs/manual.html b/memcheck/docs/manual.html index c2122f37f..2847607d1 100644 --- a/memcheck/docs/manual.html +++ b/memcheck/docs/manual.html @@ -583,6 +583,20 @@ follows: in g++-3.0.4.

+

  • --avoid-strlen-errors=yes [default]
    + --avoid-strlen-errors=no

    When enabled, valgrind + inspects each basic block it instruments for some tell-tale + literals (0xFEFEFEFF, 0x80808080, 0x00008080) which suggest + that this block is part of an inlined strlen() function. In + many cases such functions cause spurious uninitialised-value + errors to be reported -- their code is too clever for the + instrumentation scheme. This horrible hack works around the + problem, at the expense of hiding any genuine + uninitialised-value errors which might appear ine such blocks. + It is enabled by default because it is needed to get sensible + behaviour on code compiled by gcc-3.1 and above. +


  • +

  • --error-limit=yes [default]
    --error-limit=no

    When enabled, valgrind stops reporting errors after 30000 in total, or 300 different ones, diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h index e25dedba5..2f9c905c2 100644 --- a/memcheck/mc_include.h +++ b/memcheck/mc_include.h @@ -145,6 +145,10 @@ extern Bool SK_(clo_check_addrVs); /* DEBUG: clean up instrumented code? default: YES */ extern Bool SK_(clo_cleanup); +/* When instrumenting, omit some checks if tell-tale literals for + inlined strlen() are visible in the basic block. default: YES */ +extern Bool SK_(clo_avoid_strlen_errors); + /*------------------------------------------------------------*/ /*--- Functions ---*/ diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index ef9dfc49a..c2398db05 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -57,6 +57,8 @@ Bool SK_(clo_show_reachable) = False; Bool SK_(clo_workaround_gcc296_bugs) = False; Bool SK_(clo_check_addrVs) = True; Bool SK_(clo_cleanup) = True; +Bool SK_(clo_avoid_strlen_errors) = True; + /*------------------------------------------------------------*/ /*--- Profiling events ---*/ @@ -2318,6 +2320,11 @@ Bool SK_(process_cmd_line_option)(Char* arg) else if (STREQ(arg, "--cleanup=no")) SK_(clo_cleanup) = False; + else if (STREQ(arg, "--avoid-strlen-errors=yes")) + SK_(clo_avoid_strlen_errors) = True; + else if (STREQ(arg, "--avoid-strlen-errors=no")) + SK_(clo_avoid_strlen_errors) = False; + else return False; @@ -2340,7 +2347,8 @@ Char* SK_(usage)(void) " --check-addrVs=no|yes experimental lighterweight checking? [yes]\n" " yes == Valgrind's original behaviour\n" "\n" -" --cleanup=no|yes improve after instrumentation? [yes]\n"; +" --cleanup=no|yes improve after instrumentation? [yes]\n" +" --avoid-strlen-errors=no|yes suppress errs from inlined strlen [yes]\n"; } diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c index 88f34ab59..f81bde39d 100644 --- a/memcheck/mc_translate.c +++ b/memcheck/mc_translate.c @@ -498,9 +498,43 @@ static UCodeBlock* memcheck_instrument ( UCodeBlock* cb_in ) Int i, j; UInstr* u_in; Int qs, qd, qt, qtt; + Bool bogusLiterals; cb = VG_(alloc_UCodeBlock)(); cb->nextTemp = cb_in->nextTemp; + /* Scan the block to look for bogus literals. These are magic + numbers which particularly appear in hand-optimised / inlined + implementations of strlen() et al which cause so much trouble + (spurious reports of uninit-var uses). Purpose of this horrible + hack is to disable some checks any such literals are present in + this basic block. */ + bogusLiterals = False; + + if (SK_(clo_avoid_strlen_errors)) { + for (i = 0; i < cb_in->used; i++) { + u_in = &cb_in->instrs[i]; + switch (u_in->opcode) { + case ADD: case SUB: case MOV: + if (u_in->size == 4 && u_in->tag1 == Literal) + goto literal; + break; + case LEA1: + sk_assert(u_in->size == 4); + goto literal; + default: + break; + } + continue; + literal: + if (u_in->lit32 == 0xFEFEFEFF || + u_in->lit32 == 0x80808080 || + u_in->lit32 == 0x00008080) { + bogusLiterals = True; + break; + } + } + } + for (i = 0; i < cb_in->used; i++) { qs = qd = qt = qtt = INVALID_TEMPREG; u_in = &cb_in->instrs[i]; @@ -1003,7 +1037,12 @@ static UCodeBlock* memcheck_instrument ( UCodeBlock* cb_in ) if (u_in->cond != CondAlways) { sk_assert(u_in->flags_r != FlagsEmpty); qt = create_GETVF(cb, 0); - uInstr1(cb, TESTV, 0, TempReg, qt); + if (/* HACK */ bogusLiterals) { + if (0) + VG_(printf)("ignore TESTV due to bogus literal\n"); + } else { + uInstr1(cb, TESTV, 0, TempReg, qt); + } /* qt should never be referred to again. Nevertheless ... */ uInstr1(cb, SETV, 0, TempReg, qt);