~kubuntu-packagers/apport/qt5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#!/usr/bin/python

# 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')