apport-hackers team mailing list archive
-
apport-hackers team
-
Mailing list archive
-
Message #00116
[Merge] lp:~ev/apport/handle-thread-crashes into lp:apport
Evan Dandrea has proposed merging lp:~ev/apport/handle-thread-crashes into lp:apport.
Requested reviews:
Apport upstream developers (apport-hackers)
Related bugs:
Bug #1033902 in apport (Ubuntu): "Application thread crash shows application crash error alert"
https://bugs.launchpad.net/ubuntu/+source/apport/+bug/1033902
For more details, see:
https://code.launchpad.net/~ev/apport/handle-thread-crashes/+merge/135911
As mentioned in bug 1033902 and in the specification <https://wiki.ubuntu.com/ErrorTracker#thread>, we should not show the Relaunch button when an application thread crashes.
I've implemented this as a check for the process still existing, as multiple threads will share the same PID. I do not believe this will be racy - a dying PID should be gone by the time apport-{gtk,kde} is run. However, I'm happy to be told otherwise and sent back to the drawing board.
I've implemented this in both the GTK and KDE frontends and added a test that presumes we have PID 1 to fake a crash around.
--
https://code.launchpad.net/~ev/apport/handle-thread-crashes/+merge/135911
Your team Apport upstream developers is requested to review the proposed merge of lp:~ev/apport/handle-thread-crashes into lp:apport.
=== modified file 'apport/ui.py'
--- apport/ui.py 2012-11-06 15:00:35 +0000
+++ apport/ui.py 2012-11-23 14:31:22 +0000
@@ -15,7 +15,7 @@
__version__ = '2.6.2'
-import glob, sys, os.path, optparse, traceback, locale, gettext
+import glob, sys, os.path, optparse, traceback, locale, gettext, re
import errno, zlib
import subprocess, threading, webbrowser
import signal
@@ -45,6 +45,23 @@
PF_KTHREAD = 0x200000
+def get_pid(report):
+ try:
+ pid = re.search('Pid:\t(.*)\n', report.get('ProcStatus', '')).group(1)
+ return int(pid)
+ except (IndexError, AttributeError):
+ return None
+
+
+def still_running(pid):
+ try:
+ os.kill(int(pid), 0)
+ except OSError as e:
+ if e.errno == errno.ESRCH:
+ return False
+ return True
+
+
def thread_collect_info(report, reportfile, package, ui, symptom_script=None,
ignore_uninstalled=False):
'''Collect information about report.
=== modified file 'gtk/apport-gtk'
--- gtk/apport-gtk 2012-08-31 09:05:45 +0000
+++ gtk/apport-gtk 2012-11-23 14:31:22 +0000
@@ -11,7 +11,7 @@
# option) any later version. See http://www.gnu.org/copyleft/gpl.html for
# the full text of the license.
-import os.path, sys, subprocess, os, re
+import os.path, sys, subprocess, os, re, errno
from gi.repository import GObject, GLib, Wnck, GdkX11, Gdk
try:
@@ -273,13 +273,15 @@
self.w('title_label').set_label('<big><b>%s</b></big>' % t)
self.w('subtitle_label').hide()
- if 'ProcCmdline' in self.report:
+ pid = apport.ui.get_pid(self.report)
+ still_running = pid and apport.ui.still_running(pid)
+ if 'ProcCmdline' not in self.report or still_running:
+ self.w('closed_button').hide()
+ self.w('continue_button').set_label(_('Continue'))
+ else:
self.w('closed_button').show()
self.w('closed_button').set_label(_('Leave Closed'))
self.w('continue_button').set_label(_('Relaunch'))
- else:
- self.w('closed_button').hide()
- self.w('continue_button').set_label(_('Continue'))
else:
icon = 'distributor-logo'
if report_type == 'RecoverableProblem':
=== modified file 'kde/apport-kde'
--- kde/apport-kde 2012-10-11 05:47:44 +0000
+++ kde/apport-kde 2012-11-23 14:31:22 +0000
@@ -202,13 +202,16 @@
'unexpectedly.') %
desktop_info['name'])
self.text.hide()
- if 'ProcCmdline' in report:
+
+ pid = apport.ui.get_pid(report)
+ still_running = pid and apport.ui.still_running(pid)
+ if 'ProcCmdline' not in report or still_running:
+ self.closed_button.hide()
+ self.continue_button.setText(_('Continue'))
+ else:
self.closed_button.show()
self.closed_button.setText(_('Leave Closed'))
self.continue_button.setText(_('Relaunch'))
- else:
- self.closed_button.hide()
- self.continue_button.setText(_('Continue'))
else:
icon = 'distributor-logo'
self.heading.setText(_('Sorry, %s has experienced an '
=== modified file 'test/test_ui_gtk.py'
--- test/test_ui_gtk.py 2012-08-31 09:05:45 +0000
+++ test/test_ui_gtk.py 2012-11-23 14:31:22 +0000
@@ -147,6 +147,15 @@
self.assertEqual(self.app.w('subtitle_label').get_text(),
_('Package: apport 1.2.3~0ubuntu1'))
+ def test_regular_crash_thread_layout(self):
+ '''A thread of execution has failed, but the application persists.'''
+ self.app.report['ProblemType'] = 'Crash'
+ self.app.report['ProcStatus'] = 'Name:\tupstart\nPid:\t1'
+ GLib.idle_add(Gtk.main_quit)
+ self.app.ui_present_report_details(True)
+ self.assertFalse(self.app.w('closed_button').get_property('visible'))
+ self.assertEqual(self.app.w('continue_button').get_label(), _('Continue'))
+
def test_regular_crash_layout(self):
'''
+-----------------------------------------------------------------+
=== modified file 'test/test_ui_kde.py'
--- test/test_ui_kde.py 2012-08-31 09:05:45 +0000
+++ test/test_ui_kde.py 2012-11-23 14:31:22 +0000
@@ -139,6 +139,15 @@
self.assertEqual(self.app.dialog.text.text(),
_('Package: apport 1.2.3~0ubuntu1'))
+ def test_regular_crash_thread_layout(self):
+ '''A thread of execution has failed, but the application persists.'''
+ self.app.report['ProblemType'] = 'Crash'
+ self.app.report['ProcStatus'] = 'Name:\tupstart\nPid:\t1'
+ QTimer.singleShot(0, QCoreApplication.quit)
+ self.app.ui_present_report_details(True)
+ self.assertFalse(self.app.dialog.closed_button.isVisible())
+ self.assertEqual(self.app.dialog.continue_button.text(), _('Continue'))
+
def test_regular_crash_layout(self):
'''
+-----------------------------------------------------------------+