Merge lp:~brian-murray/apport/whoopsie-upload-more into lp:~apport-hackers/apport/trunk

Proposed by Brian Murray
Status: Merged
Merged at revision: 3232
Proposed branch: lp:~brian-murray/apport/whoopsie-upload-more
Merge into: lp:~apport-hackers/apport/trunk
Diff against target: 101 lines (+26/-8)
3 files modified
apport/report.py (+9/-4)
data/whoopsie-upload-all (+8/-4)
test/test_report.py (+9/-0)
To merge this branch: bzr merge lp:~brian-murray/apport/whoopsie-upload-more
Reviewer Review Type Date Requested Status
Julian Andres Klode Approve
Review via email: mp+365252@code.launchpad.net

Description of the change

For reasons unknown to me whoopsie-upload-all as it is currently written will quit if the add_gdb_info() call fails. This is different than the behavior in apport/ui.py which will pass on a failure because "we'll get stack traces on retracing". So this change modifies how add_gdb_info exits so that whoopsie-upload-all will proceed with gathering crash information and creating the .upload file. This will in turn end up fixing bug 1820132.

I wonder if there is a better way to do this though so all feedback is welcome!

To post a comment you must log in.
Revision history for this message
Julian Andres Klode (juliank) wrote :

Looks OK, although I'd go with something less string magic.

review: Approve
3231. By Brian Murray

Switch to FileNotFoundError per reviewer suggestion, add in a test for a missing executable.

Revision history for this message
Brian Murray (brian-murray) wrote :

While switching to FileNotFound makes sense it is causing issues with test/run's calling of pyflakes e.g. ./build/lib/apport/report.py:723: undefined name 'FileNotFoundError'. I'm not easily finding a way to work around that. Do you have any ideas?

Revision history for this message
Julian Andres Klode (juliank) wrote :

Oh, we should be running pyflakes3 not pyflakes, that would fix it.

Revision history for this message
Brian Murray (brian-murray) wrote :

I made the switch from pyflakes to pyflakes3 directly in trunk.

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 2019-03-15 21:53:40 +0000
3+++ apport/report.py 2019-03-29 20:51:03 +0000
4@@ -705,7 +705,8 @@
5 files there.
6
7 Raises a IOError if the core dump is invalid/truncated, or OSError if
8- calling gdb fails.
9+ calling gdb fails, or FileNotFoundError if gdb or the crashing
10+ executable cannot be found.
11 '''
12 if 'CoreDump' not in self or 'ExecutablePath' not in self:
13 return
14@@ -718,6 +719,9 @@
15 'GLibAssertionMessage': 'print __glib_assert_msg',
16 'NihAssertionMessage': 'print (char*) __nih_abort_msg'}
17 gdb_cmd, environ = self.gdb_command(rootdir, gdb_sandbox)
18+ if not gdb_cmd:
19+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
20+ 'gdb not found in retracing env')
21
22 # limit maximum backtrace depth (to avoid looped stacks)
23 gdb_cmd += ['--batch', '--ex', 'set backtrace limit 2000']
24@@ -742,6 +746,9 @@
25 reason = 'Invalid core dump: ' + warnings.strip()
26 self['UnreportableReason'] = reason
27 raise IOError(reason)
28+ elif out.split('\n')[0].endswith('No such file or directory.'):
29+ raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
30+ 'executable file for coredump not found')
31
32 # split the output into the various fields
33 part_re = re.compile(r'^\$\d+\s*=\s*-99$', re.MULTILINE)
34@@ -1544,8 +1551,7 @@
35 if gdb_sandbox else None)
36 gdb_path = _which_extrapath('gdb', gdb_sandbox_bin)
37 if not gdb_path:
38- apport.fatal('gdb does not exist in the %ssandbox nor on the host'
39- % ('gdb ' if not same_arch else ''))
40+ return '', ''
41 command = [gdb_path]
42 environ = None
43
44@@ -1587,7 +1593,6 @@
45 gdb_sandbox]
46 executable = sandbox + '/' + executable
47
48- assert os.path.exists(executable)
49 command += ['--ex', 'file "%s"' % executable]
50
51 if 'CoreDump' in self:
52
53=== modified file 'data/whoopsie-upload-all'
54--- data/whoopsie-upload-all 2016-12-10 11:28:27 +0000
55+++ data/whoopsie-upload-all 2019-03-29 20:51:03 +0000
56@@ -19,6 +19,7 @@
57 import subprocess
58 import argparse
59 import fcntl
60+import errno
61
62 import apport.fileutils
63 import apport
64@@ -78,10 +79,13 @@
65 try:
66 r.add_gdb_info()
67 except (IOError, EOFError, OSError) as e:
68- sys.stderr.write('ERROR: processing %s: %s\n' % (report, str(e)))
69- if os.path.exists(report):
70- os.unlink(report)
71- return None
72+ # the crash file won't have a Stacktrace etc but apport-retrace
73+ # could still process it
74+ if e.errno != errno.ENOENT:
75+ sys.stderr.write('ERROR: processing %s: %s\n' % (report, str(e)))
76+ if os.path.exists(report):
77+ os.unlink(report)
78+ return None
79
80 # write updated report
81 with open(report, 'ab') as f:
82
83=== modified file 'test/test_report.py'
84--- test/test_report.py 2017-07-21 19:39:25 +0000
85+++ test/test_report.py 2019-03-29 20:51:03 +0000
86@@ -644,6 +644,15 @@
87 self.assertNotIn('StacktraceTop', pr)
88 self.assertIn('core is truncated', pr['UnreportableReason'])
89
90+ def test_add_gdb_info_exe_missing(self):
91+ '''add_gdb_info() with missing executable'''
92+
93+ pr = self._generate_sigsegv_report()
94+ # change it to something that doesn't exist
95+ pr['ExecutablePath'] = pr['ExecutablePath'].replace('crash', 'gone')
96+
97+ self.assertRaises(FileNotFoundError, pr.add_gdb_info)
98+
99 def test_add_zz_parse_segv_details(self):
100 '''parse-segv produces sensible results'''
101 rep = tempfile.NamedTemporaryFile()

Subscribers

People subscribed via source and target branches