from becoming a huge performance overhead in programs with many
errors. </li><br><p>
+ <li><code>--avoid-strlen-errors=yes</code> [default]<br>
+ <code>--avoid-strlen-errors=no</code> <p>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.
+ </li><br><p>
+
<li><code>--cachesim=no</code> [default]<br>
<code>--cachesim=yes</code> <p>When enabled, turns off memory
checking, and turns on cache profiling. Cache profiling is
--D1=*,*,*) vgopts="$vgopts $arg"; shift;;
--L2=*,*,*) vgopts="$vgopts $arg"; shift;;
--weird-hacks=*) vgopts="$vgopts $arg"; shift;;
+ --avoid-strlen-errors=no) vgopts="$vgopts $arg"; shift;;
+ --avoid-strlen-errors=yes) vgopts="$vgopts $arg"; shift;;
# options for debugging Valgrind
--sanity-level=*) vgopts="$vgopts $arg"; shift;;
--single-step=yes) vgopts="$vgopts $arg"; shift;;
echo " --check-addrVs=no|yes experimental lighterweight checking? [yes]"
echo " yes == Valgrind's original behaviour"
echo " --cachesim=no|yes do cache profiling? [no]"
+ echo " --avoid-strlen-errors=no|yes suppress errs from inlined strlen? [yes]\n"
echo " --I1=<size>,<assoc>,<line_size> set I1 cache manually"
echo " --D1=<size>,<assoc>,<line_size> set D1 cache manually"
echo " --L2=<size>,<assoc>,<line_size> set L2 cache manually"
extern Bool VG_(clo_instrument);
/* DEBUG: clean up instrumented code? default: YES */
extern Bool VG_(clo_cleanup);
+/* When instrumenting, omit some checks if tell-tale literals for
+ inlined strlen() are visible in the basic block. default: YES */
+extern Bool VG_(clo_avoid_strlen_errors);
/* Cache simulation instrumentation? default: NO */
extern Bool VG_(clo_cachesim);
/* I1 cache configuration. default: undefined */
Bool VG_(clo_optimise);
Bool VG_(clo_instrument);
Bool VG_(clo_cleanup);
+Bool VG_(clo_avoid_strlen_errors);
Bool VG_(clo_cachesim);
cache_t VG_(clo_I1_cache);
cache_t VG_(clo_D1_cache);
VG_(clo_D1_cache) = UNDEFINED_CACHE;
VG_(clo_L2_cache) = UNDEFINED_CACHE;
VG_(clo_cleanup) = True;
+ VG_(clo_avoid_strlen_errors) = True;
VG_(clo_smc_check) = VG_CLO_SMC_NONE; /* note UNUSED ! */
VG_(clo_trace_syscalls) = False;
VG_(clo_trace_signals) = False;
else if (STREQ(argv[i], "--cleanup=no"))
VG_(clo_cleanup) = False;
+ else if (STREQ(argv[i], "--avoid-strlen-errors=yes"))
+ VG_(clo_avoid_strlen_errors) = True;
+ else if (STREQ(argv[i], "--avoid-strlen-errors=no"))
+ VG_(clo_avoid_strlen_errors) = False;
+
else if (STREQ(argv[i], "--cachesim=yes"))
VG_(clo_cachesim) = True;
else if (STREQ(argv[i], "--cachesim=no"))
Int i, j;
UInstr* u_in;
Int qs, qd, qt, qtt;
+ Bool bogusLiterals;
cb = VG_(allocCodeBlock)();
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 (VG_(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:
+ vg_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];
if (u_in->cond != CondAlways) {
vg_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);