Merge lp:~ev/apport/kernel-oops-crash-signature into lp:~apport-hackers/apport/trunk

Proposed by Evan
Status: Merged
Merged at revision: 2571
Proposed branch: lp:~ev/apport/kernel-oops-crash-signature
Merge into: lp:~apport-hackers/apport/trunk
Diff against target: 122 lines (+93/-2)
2 files modified
apport/report.py (+42/-2)
test/test_report.py (+51/-0)
To merge this branch: bzr merge lp:~ev/apport/kernel-oops-crash-signature
Reviewer Review Type Date Requested Status
Andy Whitcroft (community) Approve
Martin Pitt (community) Approve
Review via email: mp+129440@code.launchpad.net

Description of the change

This allows us to generate a crash_signature() from a KernelOops problem. We receive somewhere between 100 and 200 of these a day, but cannot bucket them together without a signature.

The algorithm I used came from Andy's suggested approach. I'll ask him to review this as well.

To post a comment you must log in.
Revision history for this message
Martin Pitt (pitti) wrote :

Thanks! Looks good to me.

review: Approve
Revision history for this message
Andy Whitcroft (apw) wrote :

Code looks simple enough, seems to produce reasonable looking signatures from the test cases.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'apport/report.py'
2--- apport/report.py 2012-09-28 14:49:16 +0000
3+++ apport/report.py 2012-10-12 14:22:21 +0000
4@@ -1190,8 +1190,9 @@
5 For Python crashes, this concatenates the ExecutablePath, exception
6 name, and Traceback function names, again separated by a colon.
7 '''
8- if 'ExecutablePath' not in self and not self['ProblemType'] == 'KernelCrash':
9- return None
10+ if 'ExecutablePath' not in self:
11+ if not self['ProblemType'] in ('KernelCrash', 'KernelOops'):
12+ return None
13
14 # kernel crash
15 if 'Stacktrace' in self and self['ProblemType'] == 'KernelCrash':
16@@ -1256,6 +1257,45 @@
17
18 return self['ExecutablePath'] + ':' + trace[-1].split(':')[0] + sig
19
20+ # KernelOops crashes
21+ if 'OopsText' in self:
22+ in_trace_body = False
23+ parts = []
24+ for line in self['OopsText'].split('\n'):
25+ if line.startswith('BUG: unable to handle'):
26+ parsed = re.search('^BUG: unable to handle (.*) at ', line)
27+ if parsed:
28+ match = parsed.group(1)
29+ assert match, 'could not parse expected problem type line: %s' % line
30+ parts.append(match)
31+
32+ if line.startswith('IP: '):
33+ match = self._extract_function_and_address(line)
34+ if match:
35+ parts.append(match)
36+
37+ elif line.startswith('Call Trace:'):
38+ in_trace_body = True
39+
40+ elif in_trace_body:
41+ match = None
42+ if line and line[0] == ' ':
43+ match = self._extract_function_and_address(line)
44+ if match:
45+ parts.append(match)
46+ else:
47+ in_trace_body = False
48+ if parts:
49+ return ':'.join(parts)
50+ return None
51+
52+ def _extract_function_and_address(self, line):
53+ parsed = re.search('\[.*\] (.*)$', line)
54+ if parsed:
55+ match = parsed.group(1)
56+ assert match, 'could not parse expected call trace line: %s' % line
57+ if match[0] != '?':
58+ return match
59 return None
60
61 def crash_signature_addresses(self):
62
63=== modified file 'test/test_report.py'
64--- test/test_report.py 2012-09-24 08:12:43 +0000
65+++ test/test_report.py 2012-10-12 14:22:21 +0000
66@@ -1747,6 +1747,57 @@
67 r['AssertionMessage'] = 'foo.c:42 main: i > 0'
68 self.assertEqual(r.crash_signature(), '/bin/bash:foo.c:42 main: i > 0')
69
70+ # kernel oops
71+ report = apport.report.Report('KernelOops')
72+ report['OopsText'] = '''
73+BUG: unable to handle kernel paging request at ffffb4ff
74+IP: [<c11e4690>] ext4_get_acl+0x80/0x210
75+*pde = 01874067 *pte = 00000000
76+Oops: 0000 [#1] SMP
77+Modules linked in: bnep rfcomm bluetooth dm_crypt olpc_xo1 scx200_acb snd_cs5535audio snd_ac97_codec ac97_bus snd_pcm snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq snd_timer snd_seq_device snd cs5535_gpio soundcore snd_page_alloc binfmt_misc geode_aes cs5535_mfd geode_rng msr vesafb usbhid hid 8139too pata_cs5536 8139cp
78+
79+Pid: 1798, comm: gnome-session-c Not tainted 3.0.0-11-generic #17-Ubuntu First International Computer, Inc. ION603/ION603
80+EIP: 0060:[<c11e4690>] EFLAGS: 00010286 CPU: 0
81+EIP is at ext4_get_acl+0x80/0x210
82+EAX: f5d3009c EBX: f5d30088 ECX: 00000000 EDX: f5d301d8
83+ESI: ffffb4ff EDI: 00008000 EBP: f29b3dc8 ESP: f29b3da4
84+ DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
85+Process gnome-session-c (pid: 1798, ti=f29b2000 task=f2bd72c0 task.ti=f29b2000)
86+Stack:
87+ f29b3db0 c113bb90 f5d301d8 f29b3de4 c11b9016 f5d3009c f5d30088 f5d30088
88+ 00000001 f29b3ddc c11e4cca 00000001 f5d30088 000081ed f29b3df0 c11313b7
89+ 00000021 00000021 f5d30088 f29b3e08 c1131b45 c11e4c80 f5d30088 00000021
90+Call Trace:
91+ [<c113bb90>] ? d_splice_alias+0x40/0x50
92+ [<c11b9016>] ? ext4_lookup.part.30+0x56/0x120
93+ [<c11e4cca>] ext4_check_acl+0x4a/0x90
94+ [<c11313b7>] acl_permission_check+0x97/0xa0
95+ [<c1131b45>] generic_permission+0x25/0xc0
96+ [<c11e4c80>] ? ext4_xattr_set_acl+0x160/0x160
97+ [<c1131c79>] inode_permission+0x99/0xd0
98+ [<c11e4c80>] ? ext4_xattr_set_acl+0x160/0x160
99+ [<c1131d1b>] may_open+0x6b/0x110
100+ [<c1134566>] do_last+0x1a6/0x640
101+ [<c113595d>] path_openat+0x9d/0x350
102+ [<c10de692>] ? unlock_page+0x42/0x50
103+ [<c10fb960>] ? __do_fault+0x3b0/0x4b0
104+ [<c1135c41>] do_filp_open+0x31/0x80
105+ [<c124c743>] ? aa_dup_task_context+0x33/0x60
106+ [<c1250eed>] ? apparmor_cred_prepare+0x2d/0x50
107+ [<c112e9ef>] open_exec+0x2f/0x110
108+ [<c112eef7>] ? check_unsafe_exec+0xb7/0xf0
109+ [<c112efba>] do_execve_common+0x8a/0x270
110+ [<c112f1b7>] do_execve+0x17/0x20
111+ [<c100a0a7>] sys_execve+0x37/0x70
112+ [<c15336ae>] ptregs_execve+0x12/0x18
113+ [<c152c8d4>] ? syscall_call+0x7/0xb
114+Code: 8d 76 00 8d 93 54 01 00 00 8b 32 85 f6 74 e2 8d 43 14 89 55 e4 89 45 f0 e8 2e 7e 34 00 8b 55 e4 8b 32 83 fe ff 74 07 85 f6 74 03 <3e> ff 06 8b 45 f0 e8 25 19 e4 ff 90 83 fe ff 75 b5 81 ff 00 40
115+EIP: [<c11e4690>] ext4_get_acl+0x80/0x210 SS:ESP 0068:f29b3da4
116+CR2: 00000000ffffb4ff
117+---[ end trace b567e6a3070ffb42 ]---
118+'''
119+ self.assertEqual(report.crash_signature(), 'kernel paging request:ext4_get_acl+0x80/0x210:ext4_check_acl+0x4a/0x90:acl_permission_check+0x97/0xa0:generic_permission+0x25/0xc0:inode_permission+0x99/0xd0:may_open+0x6b/0x110:do_last+0x1a6/0x640:path_openat+0x9d/0x350:do_filp_open+0x31/0x80:open_exec+0x2f/0x110:do_execve_common+0x8a/0x270:do_execve+0x17/0x20:sys_execve+0x37/0x70:ptregs_execve+0x12/0x18')
120+
121 def test_nonascii_data(self):
122 '''methods get along with non-ASCII data'''
123

Subscribers

People subscribed via source and target branches