From 6900f36727a5f664e89d0ebf9812bc4766819078 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 11 Apr 2015 09:24:09 +0200 Subject: [PATCH] Add leak_analyser shell script to analyse guarded heap info. The script runs the guarded heap allocation output through c++filt to demangle stack trace symbols and filters out a list of known globals that are never freed. It also allows to exclude further patterns provided on the command line. --- build/jam/packages/HaikuDevel | 4 + src/bin/leak_analyser.sh | 151 ++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100755 src/bin/leak_analyser.sh diff --git a/build/jam/packages/HaikuDevel b/build/jam/packages/HaikuDevel index c15e872601..b18f7d8b0a 100644 --- a/build/jam/packages/HaikuDevel +++ b/build/jam/packages/HaikuDevel @@ -82,4 +82,8 @@ if $(HAIKU_GCC_VERSION_$(architecture)[1]) = 2 { AddSymlinkToPackage data deskbar menu Applications : ../../../../apps/Debugger : Debugger ; +# Debugging tools +SEARCH on leak_analyser.sh = [ FDirName $(HAIKU_TOP) src bin ] ; +AddFilesToPackage bin : leak_analyser.sh ; + BuildHaikuPackage $(haikuDevelPackage) : haiku_devel ; diff --git a/src/bin/leak_analyser.sh b/src/bin/leak_analyser.sh new file mode 100755 index 0000000000..222388ee02 --- /dev/null +++ b/src/bin/leak_analyser.sh @@ -0,0 +1,151 @@ +#!/bin/bash + +if [ ! -f "$1" ] +then + cat << EOF + + $(basename $0) [] [] + + + + A file containing the allocations with stack traces from + the guarded heap output. + + To generate such a file run a program with the following + environment variables prefixed and pipe the output to a file: + + LD_PRELOAD=libroot_guarded.so MALLOC_DEBUG=es50 program > file + + The number after the "s" is the stack trace depth. Note that + there is an implementation defined maximum. + + --no-default-excludes + + Do not exclude known statics and globals. By default a list of + excludes is used that removes known allocations that are never + freed by the system libraries. + + --no-exclude-empty + + Do not exclude allocations with no stack trace. By default + allocations without a stack trace are excluded. This should + only happen for very early allocations where the stack trace + setting has not yet been applied. The program should not be + able to generate such allocations. + + + + Exclude allocations that match a regular expression. The + expression is matched against the whole text block of the + allocation, so can match in the header line as well as any + stack trace lines. Note that the whole block is on a single + line and newlines have been replaced with the caret (^) + character. + + Multiple exclude patterns can be specified as one argument each + and they will be ored to form the final expression. + +EOF + + exit 1 +fi + + +FILENAME="$1" +shift + + +DONE_PARSING_OPTIONS= +NO_DEFAULTS= +NO_EXCLUDE_EMPTY= +while [ -z "$DONE_PARSING_OPTIONS" ] +do + case "$1" in + --no-default-excludes) + NO_DEFAULTS=yes + shift + ;; + --no-exclude-empty) + NO_EXCLUDE_EMPTY=yes + shift + ;; + --*) + echo "unrecognized option \"$1\" ignored" + shift + ;; + *) + DONE_PARSING_OPTIONS=yes + ;; + esac +done + + +function append_pattern { + if [ -z "$EXCLUDE_PATTERN" ] + then + EXCLUDE_PATTERN="$1" + else + EXCLUDE_PATTERN="$EXCLUDE_PATTERN|$1" + fi +} + + +EXCLUDE_PATTERN="" +if [ -z "$NO_DEFAULTS" ] +then + declare -a DEFAULT_EXCLUDE_LIST=( \ + " __cxa_atexit " \ + " BPrivate::Libroot::LocaleBackend::LoadBackend" \ + " initialize_before " \ + " initialize_after " \ + " _control_input_server_" \ + " BApplication::_InitGUIContext" \ + " BApplication::_InitAppResources" \ + " BResources::LoadResource" \ + " BClipboard::_DownloadFromSystem" \ + " BToolTipManager::_InitSingleton" \ + " BPrivate::WidthBuffer::StringWidth" \ + " _init " \ + " BTranslatorRoster::Default" \ + "Translator> " \ + " icu::" \ + " icu::" \ + ) + + for EXCLUDE in "${DEFAULT_EXCLUDE_LIST[@]}" + do + append_pattern "$EXCLUDE" + done +fi + + +if [ -z "$NO_EXCLUDE_EMPTY" ] +then + append_pattern "^[^^]*\^$" +fi + + +while [ $# -gt 0 ] +do + append_pattern "$1" + shift +done + + +ALLOCATIONS=$(cat "$FILENAME" | egrep "^allocation: |^ " | tr '\n' '^' \ + | sed 's/\^a/~a/g' | tr '~' '\n' | sed 's/$/^/' | c++filt) + +if [ ! -z "$EXCLUDE_PATTERN" ] +then + ALLOCATIONS=$(echo "$ALLOCATIONS" | egrep -v "$EXCLUDE_PATTERN") +fi + +if [ -z "$ALLOCATIONS" ] +then + COUNT=0 +else + COUNT=$(echo "$ALLOCATIONS" | wc -l) +fi + + +echo "$ALLOCATIONS^total leaks: $COUNT" | tr '^' '\n' | less