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.
This commit is contained in:
Michael Lotz
2015-04-11 09:41:25 +02:00
parent 0cf3d62115
commit 6900f36727
2 changed files with 155 additions and 0 deletions
+4
View File
@@ -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 ;
+151
View File
@@ -0,0 +1,151 @@
#!/bin/bash
if [ ! -f "$1" ]
then
cat << EOF
$(basename $0) <leaksFile> [<options>] [<excludePatterns>]
<leaksFile>
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.
<excludePatterns>
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=( \
"<libroot.so> __cxa_atexit " \
"<libroot.so> BPrivate::Libroot::LocaleBackend::LoadBackend" \
"<libbe.so> initialize_before " \
"<libbe.so> initialize_after " \
"<libbe.so> _control_input_server_" \
"<libbe.so> BApplication::_InitGUIContext" \
"<libbe.so> BApplication::_InitAppResources" \
"<libbe.so> BResources::LoadResource" \
"<libbe.so> BClipboard::_DownloadFromSystem" \
"<libbe.so> BToolTipManager::_InitSingleton" \
"<libbe.so> BPrivate::WidthBuffer::StringWidth" \
"<libtracker.so> _init " \
"<libtranslation.so> BTranslatorRoster::Default" \
"Translator> " \
"<libicui18n.so.54> icu::" \
"<libicuuc.so.54> 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