-
Notifications
You must be signed in to change notification settings - Fork 12
/
kernel_diagreport2text.ksh
executable file
·151 lines (139 loc) · 4.63 KB
/
kernel_diagreport2text.ksh
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/bin/ksh
#
# kernel_diagreport2text.ksh
#
# Prints the stack trace from an OS X kernel panic diagnostic report, along
# with as much symbol translation as your mach_kernel version provides.
# By default, this is some, but with the Kernel Debug Kit, it should be a lot
# more. This is not an official Apple tool.
#
# USAGE:
# ./kernel_diagreport2text.ksh [-f kernel_file] Kernel_report.panic [...]
#
# Note: The Kernel Debug Kit currently requires an Apple ID to download. It
# would be great if this was not necessary.
#
# This script calls atos(1) for symbol translation, and also some sed/awk
# to decorate remaining untranslated symbols with kernel extension names,
# if the ranges match.
#
# This uses your current kernel, /mach_kernel, to translate symbols. If you run
# this on kernel diag reports from a different kernel version, it will print
# a "kernel version mismatch" warning, as the translation may be incorrect. Find
# a matching mach_kernel file and use the -f option to point to it.
#
# Copyright 2014 Brendan Gregg. All rights reserved.
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at docs/cddl1.txt or
# http://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at docs/cddl1.txt.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
kernel=/mach_kernel
function usage {
print "USAGE: $0 [-f kernel_file] Kernel_diag_report.panic [...]"
print " eg, $0 /Library/Logs/DiagnosticReports/Kernel_2014-05-26-124827_bgregg.panic"
exit
}
(( $# == 0 )) && usage
[[ $1 == "-h" || $1 == "--help" ]] && usage
if [[ $1 == "-f" ]]; then
kernel=$2
if [[ ! -e $kernel ]]; then
print -u2 "ERROR: Kernel $kernel not found. Quitting."
exit 2
fi
shift 2
fi
if [[ ! -x /usr/bin/atos ]]; then
print -u2 "ERROR: Couldn't find, and need, /usr/bin/atos. Is this part of Xcode? Quitting..."
exit 2
fi
while (( $# != 0 )); do
if [[ "$file" != "" ]]; then print; fi
file=$1
shift
echo "File $file"
if [[ ! -e $file ]]; then
print "ERROR: File $file not found. Skipping."
continue
fi
# Find slide address
slide=$(awk '/^Kernel slide:.*0x/ { print $3 }' $file)
if [[ "$slide" == "" ]]; then
print -n "ERROR: Missing \"Kernel slide:\" line, so can't process $file. "
print "This is needed for atos -s. Is this really a Kernel diag panic file?"
continue
fi
# Print panic line
grep '^panic' $file
# Check kernel version match (uname -v string)
kernel_ver=$(strings -a $kernel | grep 'Darwin Kernel Version')
panic_ver=$(grep 'Darwin Kernel Version' $file)
warn=""
if [[ "$kernel_ver" != "$panic_ver" ]]; then
print "WARNING: kernel version mismatch (use -f):"
printf "%14s: %s\n" "$kernel" "$kernel_ver"
printf "%14s: %s\n" "panic file" "$panic_ver"
warn=" (may be incorrect due to mismatch)"
fi
# Find kernel extension ranges
i=0
unset name start end
awk 'ext == 1 && /0x.*->.*0x/ {
gsub(/\[.*\]/, ""); gsub(/@/, " "); gsub(/->/, " ")
print $0
}
/Kernel Extensions in backtrace/ { ext = 1 }
/^$/ { ext = 0 }
' < $file | while read n s e; do
# the awk gsub's convert this line:
# com.apple.driver.AppleUSBHub(666.4)[CD9B71FF-2FDD-3BC4-9C39-5E066F66D158]@0xffffff7f84ed2000->0xffffff7f84ee9fff
# into this:
# com.apple.driver.AppleUSBHub(666.4) 0xffffff7f84ed2000 0xffffff7f84ee9fff
# which can then be read as three fields
name[i]=$n
start[i]=$s
end[i]=$e
(( i++ ))
done
# Print and translate stack
print "Stack$warn:"
awk 'backtrace == 1 && /^[^ ]/ { print $3 }
/Backtrace.*Return Address/ { backtrace = 1 }
/^$/ { backtrace = 0 }
' < $file | atos -d -o $kernel -s $slide | while read line; do
# do extensions
if [[ $line =~ 0x* ]]; then
i=0
while (( i <= ${#name[@]} )); do
[[ "${start[i]}" == "" ]] && break
# assuming fixed width addresses, use string comparison:
if [[ $line > ${start[$i]} && $line < ${end[$i]} ]]; then
line="$line (in ${name[$i]})"
break
fi
(( i++ ))
done
fi
print " $line"
done
# Print other key details
awk '/^BSD process name/ { gsub(/ corresponding to current thread/, ""); print $0 }
ver == 1 { print "Mac OS version:", $0; ver = 0 }
/^Mac OS version/ { ver = 1 }
' < $file
done