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:
@@ -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 ;
|
||||
|
||||
Executable
+151
@@ -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
|
||||
Reference in New Issue
Block a user