| Index: tools/valgrind/memcheck_analyze.py
|
| ===================================================================
|
| --- tools/valgrind/memcheck_analyze.py (revision 97109)
|
| +++ tools/valgrind/memcheck_analyze.py (working copy)
|
| @@ -25,13 +25,23 @@
|
| # Global symbol table (yuck)
|
| TheAddressTable = None
|
|
|
| -# These are functions (using C++ mangled names) that we look for in stack
|
| -# traces. We don't show stack frames while pretty printing when they are below
|
| -# any of the following:
|
| -_TOP_OF_STACK_POINTS = [
|
| - # Don't show our testing framework.
|
| - "testing::Test::Run()",
|
| +# These are regexps that define functions (using C++ mangled names)
|
| +# we don't want to see in stack traces while pretty printing
|
| +# or generating suppressions.
|
| +# Just stop printing the stack/suppression frames when the current one
|
| +# matches any of these.
|
| +_BORING_CALLERS = [
|
| + # TODO(timurrrr): add more boring callers when needed
|
| +
|
| + # Don't show our testing framework:
|
| "_ZN7testing4Test3RunEv",
|
| + "_ZN7testing8internal35HandleExceptionsInMethodIfSupported.*",
|
| + "_ZN7testing8internal38HandleSehExceptionsInMethodIfSupported.*",
|
| +
|
| + # Depends on scheduling:
|
| + "_ZN11MessageLoop3RunEv",
|
| + "_ZN14RunnableMethod.*",
|
| +
|
| # Also don't show the internals of libc/pthread.
|
| "start_thread"
|
| ]
|
| @@ -95,9 +105,18 @@
|
| SRC_FILE_NAME : getTextOf(frame, SRC_FILE_NAME),
|
| SRC_LINE : getTextOf(frame, SRC_LINE)
|
| }
|
| +
|
| + # Ignore this frame and all the following if it's a "boring" function.
|
| + enough_frames = False
|
| + for regexp in _BORING_CALLERS:
|
| + if re.match("^%s$" % regexp, frame_dict[FUNCTION_NAME]):
|
| + enough_frames = True
|
| + break
|
| + if enough_frames:
|
| + break
|
| +
|
| frames += [frame_dict]
|
| - if frame_dict[FUNCTION_NAME] in _TOP_OF_STACK_POINTS:
|
| - break
|
| +
|
| global TheAddressTable
|
| if TheAddressTable != None and frame_dict[SRC_LINE] == "":
|
| # Try using gdb
|
| @@ -265,25 +284,39 @@
|
| supp = supp.replace("fun:_Znwm", "fun:_Znw*")
|
| supp = supp.replace("fun:_Znaj", "fun:_Zna*")
|
| supp = supp.replace("fun:_Znam", "fun:_Zna*")
|
| +
|
| # Split into lines so we can enforce length limits
|
| supplines = supp.split("\n")
|
| + supp = None # to avoid re-use
|
|
|
| # Truncate at line 26 (VG_MAX_SUPP_CALLERS plus 2 for name and type)
|
| # or at the first 'boring' caller.
|
| # (https://bugs.kde.org/show_bug.cgi?id=199468 proposes raising
|
| # VG_MAX_SUPP_CALLERS, but we're probably fine with it as is.)
|
| - # TODO(dkegel): add more boring callers
|
| - newlen = 26;
|
| - for boring_caller in [" fun:_ZN11MessageLoop3RunEv",
|
| - " fun:_ZN7testing4Test3RunEv"]:
|
| - try:
|
| - newlen = min(newlen, supplines.index(boring_caller))
|
| - except ValueError:
|
| - pass
|
| + newlen = min(26, len(supplines));
|
| +
|
| + # Drop boring frames and all the following.
|
| + enough_frames = False
|
| + for frameno in range(newlen):
|
| + for boring_caller in _BORING_CALLERS:
|
| + if re.match("^ +fun:%s$" % boring_caller, supplines[frameno]):
|
| + newlen = frameno
|
| + enough_frames = True
|
| + break
|
| + if enough_frames:
|
| + break
|
| if (len(supplines) > newlen):
|
| supplines = supplines[0:newlen]
|
| supplines.append("}")
|
|
|
| + for frame in range(len(supplines)):
|
| + # Replace the always-changing anonymous namespace prefix with "*".
|
| + m = re.match("( +fun:)_ZN.*_GLOBAL__N_.*\.cc_" +
|
| + "[0-9a-fA-F]{8}_[0-9a-fA-F]{8}(.*)",
|
| + supplines[frame])
|
| + if m:
|
| + supplines[frame] = "*".join(m.groups())
|
| +
|
| output += "\n".join(supplines) + "\n"
|
|
|
| return output
|
|
|