mirror of https://gitee.com/openkylin/apport.git
175 lines
5.3 KiB
Python
Executable File
175 lines
5.3 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
# Use the coredump in a crash report to regenerate the stack traces. This is
|
|
# helpful to get a trace with debug symbols.
|
|
#
|
|
# Copyright (c) 2006 - 2013 Canonical Ltd.
|
|
# Authors: Alex Chiang <alex.chiang@canonical.com>
|
|
# Kyle Nitzsche <kyle.nitzsche@canonical.com>
|
|
# Martin Pitt <martin.pitt@ubuntu.com>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License as published by the
|
|
# Free Software Foundation; either version 2 of the License, or (at your
|
|
# option) any later version. See http://www.gnu.org/copyleft/gpl.html for
|
|
# the full text of the license.
|
|
|
|
import sys
|
|
import os
|
|
import os.path
|
|
import subprocess
|
|
import argparse
|
|
import gettext
|
|
|
|
import apport
|
|
import apport.fileutils
|
|
import apport.sandboxutils
|
|
from apport import unicode_gettext as _
|
|
|
|
#
|
|
# functions
|
|
#
|
|
|
|
|
|
def parse_options():
|
|
'''Parse command line options and return options.'''
|
|
|
|
description = _("See man page for details.")
|
|
|
|
parser = argparse.ArgumentParser(description=description)
|
|
|
|
parser.add_argument(
|
|
'-l', '--log', metavar='LOGFILE', default='valgrind.log',
|
|
help=_('specify the log file name produced by valgrind'))
|
|
parser.add_argument(
|
|
'--sandbox-dir', metavar='SDIR',
|
|
help=_('reuse a previously created sandbox dir (SDIR) or, if it does '
|
|
'not exist, create it'))
|
|
parser.add_argument(
|
|
'--no-sandbox', action='store_true',
|
|
help=_('do not create or reuse a sandbox directory for additional '
|
|
'debug symbols but rely only on installed debug symbols.'))
|
|
parser.add_argument(
|
|
'-C', '--cache', metavar='DIR',
|
|
help=_('reuse a previously created cache dir (CDIR) or, if it does '
|
|
'not exist, create it'))
|
|
parser.add_argument(
|
|
'-v', '--verbose', action='store_true',
|
|
help=_('report download/install progress when installing packages '
|
|
'into sandbox'))
|
|
parser.add_argument(
|
|
'exe', metavar='EXECUTABLE',
|
|
help=_('the executable that is run under valgrind\'s memcheck tool '
|
|
' for memory leak detection'))
|
|
parser.add_argument(
|
|
'-p', '--extra-package', metavar='PKG', action='append', default=[],
|
|
help=_('Install an extra package into the sandbox (can be specified '
|
|
'multiple times)'))
|
|
opts = parser.parse_args()
|
|
|
|
return opts
|
|
|
|
|
|
def _exit_on_interrupt():
|
|
sys.exit(1)
|
|
|
|
#
|
|
# main
|
|
#
|
|
|
|
|
|
options = parse_options()
|
|
|
|
try:
|
|
apport.memdbg('start')
|
|
apport.memdbg('Executable: ' + options.exe)
|
|
apport.memdbg('Command arguments: ' + str(options))
|
|
|
|
gettext.textdomain('apport')
|
|
|
|
# get and verify path to executable
|
|
exepath = subprocess.Popen(
|
|
['which', options.exe], stdout=subprocess.PIPE).communicate()[0]
|
|
exepath = bytes.decode(exepath)
|
|
exepath = exepath.rstrip('\n')
|
|
exepath = os.path.abspath(exepath)
|
|
if not exepath:
|
|
sys.stderr.write(_('Error: %s is not an executable. Stopping.') % options.exe)
|
|
sys.stderr.write('\n')
|
|
sys.exit(1)
|
|
except (KeyboardInterrupt, SystemExit):
|
|
sys.stderr.write("\nInterrupted during initialization\n")
|
|
_exit_on_interrupt()
|
|
|
|
try:
|
|
if (not options.no_sandbox):
|
|
# create report unless in no-sandbox mode
|
|
report = apport.Report()
|
|
|
|
report['ExecutablePath'] = exepath
|
|
report.add_os_info()
|
|
report.add_package_info()
|
|
|
|
apport.memdbg('\nCreated report')
|
|
except (KeyboardInterrupt, SystemExit):
|
|
sys.stderr.write("\nInterrupted during report creation\n")
|
|
_exit_on_interrupt()
|
|
|
|
|
|
apport.memdbg('About to handle sandbox')
|
|
|
|
cache = None
|
|
|
|
try:
|
|
# make the sandbox unless not wanted
|
|
if not options.no_sandbox:
|
|
sandbox, cache, outdated_msg = apport.sandboxutils.make_sandbox(
|
|
report, "system", options.cache, options.sandbox_dir,
|
|
options.extra_package, options.verbose)
|
|
|
|
except (KeyboardInterrupt, SystemExit):
|
|
sys.stderr.write("\nInterrupted while creating sandbox\n")
|
|
_exit_on_interrupt()
|
|
|
|
apport.memdbg('About to get path to sandbox')
|
|
|
|
debugrootdir = None
|
|
|
|
try:
|
|
if not options.no_sandbox:
|
|
# get path to sandbox
|
|
if sandbox:
|
|
# sandbox is only defined when an auto created dir in tmp is in use
|
|
debugrootdir = os.path.abspath(sandbox)
|
|
elif options.sandbox_dir:
|
|
# this is used when --sandbox-dir is passed as arg
|
|
debugrootdir = os.path.abspath(options.sandbox_dir)
|
|
|
|
# display sandbox and cache dirs, if any
|
|
if debugrootdir:
|
|
print('Sandbox directory:', debugrootdir)
|
|
if cache:
|
|
print('Cache directory:', cache)
|
|
|
|
# prep to run valgrind
|
|
argv = ['valgrind']
|
|
argv += ['-v', '--tool=memcheck', '--leak-check=full', '--num-callers=40']
|
|
argv += ['--log-file=%s' % options.log]
|
|
argv += ['--track-origins=yes']
|
|
if (not options.no_sandbox):
|
|
argv += ['--extra-debuginfo-path=%s/usr/lib/debug/' % debugrootdir]
|
|
argv += [exepath]
|
|
|
|
apport.memdbg('before calling valgrind')
|
|
except (KeyboardInterrupt, SystemExit):
|
|
sys.stderr.write("\nInterrupted while preparing to create sandbox\n")
|
|
_exit_on_interrupt()
|
|
|
|
try:
|
|
subprocess.call(argv)
|
|
except (KeyboardInterrupt, SystemExit):
|
|
sys.stderr.write("\nInterrupted while running valgrind\n")
|
|
_exit_on_interrupt()
|
|
|
|
apport.memdbg('information collection done')
|