-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathqcrashdumper
executable file
·116 lines (106 loc) · 3.54 KB
/
qcrashdumper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/bin/sh
# arguments :
# 1) minidump file (*.dmp)
# 2) symbol files directory; on Windows, path where *.pdb files are, on Linux path where binaries are
# example : qcrashdumper mydumpfile.dmp ~/Desktop/Repos/binaries
# get args
dmp_file=$1
bin_dir=$2
# check running machine
uname_out="$(uname -s)"
case "${uname_out}" in
Linux*) machine=Linux;;
Darwin*) machine=Mac;;
CYGWIN*) machine=Win;;
MINGW*) machine=Win;;
MSYS*) machine=Win;;
*) machine="UNKNOWN:${uname_os}"
esac
#echo "[INFO] machine is ${machine}."
# check arg
if [[ ! "${dmp_file}" ]]; then
printf "\n[ERROR] missing first argument; provide minidump file (*.dmp)\n\n" >&2;
exit 1;
fi
if [[ ! -d "${bin_dir}" ]]; then
if [[ $machine == "Win" ]]; then
printf "\n[ERROR] missing second argument; provide symbols files path (*.pdb)\n\n" >&2;
else
printf "\n[ERROR] missing second argument; provide symbols files path\n\n" >&2;
fi
exit 1;
fi
# try to add relevant paths
scr_dir="$(dirname "$(readlink -f "$0")")"
if ! type "dump_syms" > /dev/null 2>&1; then
if [[ $machine == "Win" ]]; then
PATH="${PATH}:${scr_dir}/../deps/breakpad.git/src/tools/windows/binaries"
else
PATH="${PATH}:${scr_dir}/../deps/breakpad.git/src/tools/linux/dump_syms"
fi
fi
if ! type "minidump_stackwalk" > /dev/null 2>&1; then
PATH="${PATH}:${scr_dir}/../deps/breakpad.git/src/processor"
fi
# check for dependencies
if ! type "dump_syms" > /dev/null 2>&1; then
echo "[ERROR] dump_syms not found in PATH."
exit 1
fi
if ! type "minidump_stackwalk" > /dev/null 2>&1; then
echo "[ERROR] minidump_stackwalk not found in PATH."
exit 1
fi
# clear any previous symbols dir
if [[ -d "symbols" ]]; then
rm -rf "symbols"
fi
# find out which dependencies minidump_stackwalk is expecting
sym_marker="No symbol file at "
IFS=$'\n'
list_lines=( $(minidump_stackwalk "${dmp_file}" symbols 2>&1 | grep "${sym_marker}") )
for f in ${!list_lines[@]}; do
curr_line=${list_lines[$f]}
# remove up to marker
curr_line="${curr_line#*${sym_marker}}"
# overwrite array entry
list_lines[$f]=${curr_line}
IFS=$'/'
list_parts=( ${curr_line} )
# read parts
sym_dir=${list_parts[0]}
bin_file=${list_parts[1]}
uniq_dir=${list_parts[2]}
sym_file=${list_parts[3]}
# check if binary dependency exists in given binary path
bin_filepath=${bin_dir}/${bin_file}
# on linux, debug symbols might be in the binary itself or in the file pointed by the gnu_debuglink stored in the binary file
if [[ $machine == "Linux" ]]; then
# read gnu_debuglink
sym_file=$(readelf --string-dump=.gnu_debuglink "${bin_filepath}" | sed -n '/]/{s/.* //;p;q}')
# if gnu_debuglink file exists, then use pointed file to extract symbols instead
if [[ ! -e ${sym_file} ]]; then
sym_file=${bin_dir}/${sym_file}
fi
if [ -f "${sym_file}" ]; then
bin_filepath="${sym_file}"
fi
fi
if [[ ! -e ${bin_filepath} ]]; then
echo "[WARN] ${bin_file} not found in given path, could not create ${sym_file}."
continue
fi
# create target symbols dir
mkdir -p "${sym_dir}"
mkdir -p "${sym_dir}/${bin_file}"
mkdir -p "${sym_dir}/${bin_file}/${uniq_dir}"
dump_syms "${bin_filepath}" > ${curr_line}
echo "[INFO] ${curr_line} created successfully."
done
# get analysis and put in file
dmp_basefile=$(basename "${dmp_file}")
minidump_stackwalk "${dmp_file}" symbols > ${dmp_basefile}.txt 2>&1
# print 50 lines after "Crash" match
awk '/Crash/ {for(i=1; i<=50; i++) {getline; print}}' ${dmp_basefile}.txt
echo ""
echo "[INFO] full results written down to ${dmp_basefile}.txt."