← Back to team overview

apport-hackers team mailing list archive

[Merge] lp:~ev/apport/kernel-oops-crash-signature into lp:apport

 

Evan Dandrea has proposed merging lp:~ev/apport/kernel-oops-crash-signature into lp:apport.

Requested reviews:
  Andy Whitcroft (apw)
  Apport upstream developers (apport-hackers)

For more details, see:
https://code.launchpad.net/~ev/apport/kernel-oops-crash-signature/+merge/129440

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.
-- 
https://code.launchpad.net/~ev/apport/kernel-oops-crash-signature/+merge/129440
Your team Apport upstream developers is requested to review the proposed merge of lp:~ev/apport/kernel-oops-crash-signature into lp:apport.
=== modified file 'apport/report.py'
--- apport/report.py	2012-09-28 14:49:16 +0000
+++ apport/report.py	2012-10-12 14:22:21 +0000
@@ -1190,8 +1190,9 @@
         For Python crashes, this concatenates the ExecutablePath, exception
         name, and Traceback function names, again separated by a colon.
         '''
-        if 'ExecutablePath' not in self and not self['ProblemType'] == 'KernelCrash':
-            return None
+        if 'ExecutablePath' not in self:
+            if not self['ProblemType'] in ('KernelCrash', 'KernelOops'):
+                return None
 
         # kernel crash
         if 'Stacktrace' in self and self['ProblemType'] == 'KernelCrash':
@@ -1256,6 +1257,45 @@
 
             return self['ExecutablePath'] + ':' + trace[-1].split(':')[0] + sig
 
+        # KernelOops crashes
+        if 'OopsText' in self:
+            in_trace_body = False
+            parts = []
+            for line in self['OopsText'].split('\n'):
+                if line.startswith('BUG: unable to handle'):
+                    parsed = re.search('^BUG: unable to handle (.*) at ', line)
+                    if parsed:
+                        match = parsed.group(1)
+                        assert match, 'could not parse expected problem type line: %s' % line
+                        parts.append(match)
+
+                if line.startswith('IP: '):
+                    match = self._extract_function_and_address(line)
+                    if match:
+                        parts.append(match)
+
+                elif line.startswith('Call Trace:'):
+                    in_trace_body = True
+
+                elif in_trace_body:
+                    match = None
+                    if line and line[0] == ' ':
+                        match = self._extract_function_and_address(line)
+                        if match:
+                            parts.append(match)
+                    else:
+                        in_trace_body = False
+            if parts:
+                return ':'.join(parts)
+        return None
+
+    def _extract_function_and_address(self, line):
+        parsed = re.search('\[.*\] (.*)$', line)
+        if parsed:
+            match = parsed.group(1)
+            assert match, 'could not parse expected call trace line: %s' % line
+            if match[0] != '?':
+                return match
         return None
 
     def crash_signature_addresses(self):

=== modified file 'test/test_report.py'
--- test/test_report.py	2012-09-24 08:12:43 +0000
+++ test/test_report.py	2012-10-12 14:22:21 +0000
@@ -1747,6 +1747,57 @@
         r['AssertionMessage'] = 'foo.c:42 main: i > 0'
         self.assertEqual(r.crash_signature(), '/bin/bash:foo.c:42 main: i > 0')
 
+        # kernel oops
+        report = apport.report.Report('KernelOops')
+        report['OopsText'] = '''
+BUG: unable to handle kernel paging request at ffffb4ff
+IP: [<c11e4690>] ext4_get_acl+0x80/0x210
+*pde = 01874067 *pte = 00000000
+Oops: 0000 [#1] SMP
+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
+
+Pid: 1798, comm: gnome-session-c Not tainted 3.0.0-11-generic #17-Ubuntu First International Computer, Inc.  ION603/ION603
+EIP: 0060:[<c11e4690>] EFLAGS: 00010286 CPU: 0
+EIP is at ext4_get_acl+0x80/0x210
+EAX: f5d3009c EBX: f5d30088 ECX: 00000000 EDX: f5d301d8
+ESI: ffffb4ff EDI: 00008000 EBP: f29b3dc8 ESP: f29b3da4
+ DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
+Process gnome-session-c (pid: 1798, ti=f29b2000 task=f2bd72c0 task.ti=f29b2000)
+Stack:
+ f29b3db0 c113bb90 f5d301d8 f29b3de4 c11b9016 f5d3009c f5d30088 f5d30088
+ 00000001 f29b3ddc c11e4cca 00000001 f5d30088 000081ed f29b3df0 c11313b7
+ 00000021 00000021 f5d30088 f29b3e08 c1131b45 c11e4c80 f5d30088 00000021
+Call Trace:
+ [<c113bb90>] ? d_splice_alias+0x40/0x50
+ [<c11b9016>] ? ext4_lookup.part.30+0x56/0x120
+ [<c11e4cca>] ext4_check_acl+0x4a/0x90
+ [<c11313b7>] acl_permission_check+0x97/0xa0
+ [<c1131b45>] generic_permission+0x25/0xc0
+ [<c11e4c80>] ? ext4_xattr_set_acl+0x160/0x160
+ [<c1131c79>] inode_permission+0x99/0xd0
+ [<c11e4c80>] ? ext4_xattr_set_acl+0x160/0x160
+ [<c1131d1b>] may_open+0x6b/0x110
+ [<c1134566>] do_last+0x1a6/0x640
+ [<c113595d>] path_openat+0x9d/0x350
+ [<c10de692>] ? unlock_page+0x42/0x50
+ [<c10fb960>] ? __do_fault+0x3b0/0x4b0
+ [<c1135c41>] do_filp_open+0x31/0x80
+ [<c124c743>] ? aa_dup_task_context+0x33/0x60
+ [<c1250eed>] ? apparmor_cred_prepare+0x2d/0x50
+ [<c112e9ef>] open_exec+0x2f/0x110
+ [<c112eef7>] ? check_unsafe_exec+0xb7/0xf0
+ [<c112efba>] do_execve_common+0x8a/0x270
+ [<c112f1b7>] do_execve+0x17/0x20
+ [<c100a0a7>] sys_execve+0x37/0x70
+ [<c15336ae>] ptregs_execve+0x12/0x18
+ [<c152c8d4>] ? syscall_call+0x7/0xb
+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
+EIP: [<c11e4690>] ext4_get_acl+0x80/0x210 SS:ESP 0068:f29b3da4
+CR2: 00000000ffffb4ff
+---[ end trace b567e6a3070ffb42 ]---
+'''
+        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')
+
     def test_nonascii_data(self):
         '''methods get along with non-ASCII data'''