← Back to team overview

apport-hackers team mailing list archive

[Merge] lp:~brian-murray/apport/sandbox-gdb into lp:apport

 

Brian Murray has proposed merging lp:~brian-murray/apport/sandbox-gdb into lp:apport.

Requested reviews:
  Apport upstream developers (apport-hackers)
Related bugs:
  Bug #1659122 in Apport: "install_packages() makes an assumption that a downloaded package has been extracted"
  https://bugs.launchpad.net/apport/+bug/1659122

For more details, see:
https://code.launchpad.net/~brian-murray/apport/sandbox-gdb/+merge/315619

This adds an option, --gdb-sandbox, to apport-retrace that will install gdb in the report's sandbox (if it is the same architecture as the host) or create another sandbox using the distribution from the report and the host's architecture.  This makes it so that users of apport-retrace do not need to have gdb or gdb-multiarch installed on their system and ensures that a modern version of gdb is being used to retrace the crash.

Some of the changes, choosing which gdb to use, are from work Martin did in revision r3076 of apport.

One thing I don't feel great about is the way os.environ is modified and restored for LD_LIBRARY_PATH etc as the code is duplicated in apport-retrace and apport/report.py so suggestions welcome there!
-- 
Your team Apport upstream developers is requested to review the proposed merge of lp:~brian-murray/apport/sandbox-gdb into lp:apport.
=== modified file 'apport/report.py'
--- apport/report.py	2016-12-18 12:50:20 +0000
+++ apport/report.py	2017-01-25 19:24:04 +0000
@@ -213,6 +213,21 @@
 
     return False
 
+
+def _which_extrapath(command, extra_path):
+    '''Return path of command, preferring extra_path'''
+
+    if extra_path:
+        env = os.environ.copy()
+        env['PATH'] = extra_path + ':' + env.get('PATH', '')
+    else:
+        env = None
+    try:
+        return subprocess.check_output(['which', command], env=env).decode().strip()
+    except subprocess.CalledProcessError:
+        return None
+
+
 #
 # Report class
 #
@@ -661,7 +676,7 @@
                 os.unlink(core)
         return ret
 
-    def add_gdb_info(self, rootdir=None):
+    def add_gdb_info(self, rootdir=None, gdb_sandbox=None):
         '''Add information from gdb.
 
         This requires that the report has a CoreDump and an
@@ -693,8 +708,7 @@
                        'AssertionMessage': 'print __abort_msg->msg',
                        'GLibAssertionMessage': 'print __glib_assert_msg',
                        'NihAssertionMessage': 'print (char*) __nih_abort_msg'}
-
-        gdb_cmd = self.gdb_command(rootdir)
+        gdb_cmd = self.gdb_command(rootdir, gdb_sandbox)
 
         # limit maximum backtrace depth (to avoid looped stacks)
         gdb_cmd += ['--batch', '--ex', 'set backtrace limit 2000']
@@ -705,8 +719,18 @@
             value_keys.append(name)
             gdb_cmd += ['--ex', 'p -99', '--ex', cmd]
 
+        if gdb_sandbox:
+            # these env settings will be modified when gdb is called
+            orig_ld_lib_path = os.environ.get('LD_LIBRARY_PATH', '')
+            orig_pyhome = os.environ.get('PYTHONHOME', '')
+            orig_gconv_path = os.environ.get('GCONV_PATH', '')
         # call gdb (might raise OSError)
         out = _command_output(gdb_cmd).decode('UTF-8', errors='replace')
+        if gdb_sandbox:
+            # restore original env settings
+            os.environ['LD_LIBRARY_PATH'] = orig_ld_lib_path
+            os.environ['PYTHONHOME'] = orig_pyhome
+            os.environ['GCONV_PATH'] = orig_gconv_path
 
         # check for truncated stack trace
         if 'is truncated: expected core file size' in out:
@@ -1490,7 +1514,7 @@
                     else:
                         self[k] = pattern.sub(repl, self[k])
 
-    def gdb_command(self, sandbox):
+    def gdb_command(self, sandbox, gdb_sandbox=None):
         '''Build gdb command for this report.
 
         This builds a gdb command for processing the given report, by setting
@@ -1506,15 +1530,22 @@
         assert 'ExecutablePath' in self
         executable = self.get('InterpreterPath', self['ExecutablePath'])
 
-        command = ['gdb']
-
-        if 'Architecture' in self and self['Architecture'] != packaging.get_system_architecture():
+        same_arch = False
+        if 'Architecture' in self and self['Architecture'] == packaging.get_system_architecture():
+            same_arch = True
+
+        gdb_sandbox_bin = gdb_sandbox and os.path.join(gdb_sandbox, 'usr', 'bin') or None
+        gdb_path = _which_extrapath('gdb', gdb_sandbox_bin)
+        if not gdb_path:
+            apport.fatal('gdb does not exist in the %ssandbox nor on the host'
+                         % ('gdb ' if not same_arch else ''))
+        command = [gdb_path]
+
+        if not same_arch:
             # check if we have gdb-multiarch
-            which = subprocess.Popen(['which', 'gdb-multiarch'],
-                                     stdout=subprocess.PIPE)
-            which.communicate()
-            if which.returncode == 0:
-                command = ['gdb-multiarch']
+            ma = _which_extrapath('gdb-multiarch', gdb_sandbox_bin)
+            if ma:
+                command = [ma]
             else:
                 sys.stderr.write(
                     'WARNING: Please install gdb-multiarch for processing '
@@ -1522,8 +1553,25 @@
                     'will be very poor.\n')
 
         if sandbox:
+            # N.B. set solib-absolute-prefix is an alias for set sysroot
             command += ['--ex', 'set debug-file-directory %s/usr/lib/debug' % sandbox,
                         '--ex', 'set solib-absolute-prefix ' + sandbox]
+            if gdb_sandbox:
+                native_multiarch = "x86_64-linux-gnu"
+                ld_lib_path = '%s/lib:%s/lib/%s:%s/usr/lib/%s:%s/usr/lib' % \
+                               (gdb_sandbox, gdb_sandbox, native_multiarch, gdb_sandbox, native_multiarch, gdb_sandbox)
+                pyhome = '%s/usr' % gdb_sandbox
+                # env settings need to be modified for gdb
+                orig_ld_lib_path = os.environ.get('LD_LIBRARY_PATH', '')
+                orig_pyhome = os.environ.get('PYTHONHOME', '')
+                orig_gconv_path = os.environ.get('GCONV_PATH', '')
+                os.environ['LD_LIBRARY_PATH'] = ld_lib_path
+                os.environ['PYTHONHOME'] = pyhome
+                os.environ['GCONV_PATH'] = '%s/usr/lib/%s/gconv' % (gdb_sandbox,
+                                                                    native_multiarch)
+                command.insert(0, '%s/lib/%s/ld-linux-x86-64.so.2' % (gdb_sandbox, native_multiarch))
+                command += ['--ex', 'set data-directory %s/usr/share/gdb' % gdb_sandbox,
+                            '--ex', 'set auto-load safe-path ' + sandbox]
             executable = sandbox + '/' + executable
 
         assert os.path.exists(executable)

=== modified file 'apport/sandboxutils.py'
--- apport/sandboxutils.py	2016-05-11 10:43:40 +0000
+++ apport/sandboxutils.py	2017-01-25 19:24:04 +0000
@@ -138,7 +138,8 @@
     deleted at program exit.
 
     extra_packages can specify a list of additional packages to install which
-    are not derived from the report.
+    are not derived from the report and will be installed along with their
+    dependencies.
 
     If verbose is True (False by default), this will write some additional
     logging to stdout.
@@ -181,8 +182,10 @@
         pkgs = needed_packages(report)
 
     # add user-specified extra packages, if any
+    extra_pkgs = []
     for p in extra_packages:
-        pkgs.append((p, None))
+        extra_pkgs.append((p, None))
+
     if config_dir == 'system':
         config_dir = None
 
@@ -202,6 +205,16 @@
             architecture=report.get('Architecture'), origins=origins)
     except SystemError as e:
         apport.fatal(str(e))
+    # install the extra packages and their deps
+    if extra_pkgs:
+        try:
+            outdated_msg += apport.packaging.install_packages(
+                sandbox_dir, config_dir, report['DistroRelease'], extra_pkgs,
+                verbose, cache_dir, permanent_rootdir,
+                architecture=report.get('Architecture'), origins=origins,
+                install_deps=True)
+        except SystemError as e:
+            apport.fatal(str(e))
 
     pkg_versions = report_package_versions(report)
     pkgs = needed_runtime_packages(report, sandbox_dir, pkgmap_cache_dir, pkg_versions, verbose)

=== modified file 'backends/packaging-apt-dpkg.py'
--- backends/packaging-apt-dpkg.py	2016-12-10 11:28:27 +0000
+++ backends/packaging-apt-dpkg.py	2017-01-25 19:24:04 +0000
@@ -46,6 +46,7 @@
     def __init__(self):
         self._apt_cache = None
         self._sandbox_apt_cache = None
+        self._sandbox_apt_cache_arch = None
         self._contents_dir = None
         self._mirror = None
         self._virtual_mapping_obj = None
@@ -93,17 +94,19 @@
                 self._apt_cache = apt.Cache(rootdir='/')
         return self._apt_cache
 
-    def _sandbox_cache(self, aptroot, apt_sources, fetchProgress, distro_name, release_codename, origins):
+    def _sandbox_cache(self, aptroot, apt_sources, fetchProgress, distro_name,
+                       release_codename, origins, arch):
         '''Build apt sandbox and return apt.Cache(rootdir=) (initialized lazily).
 
         Clear the package selection on subsequent calls.
         '''
         self._apt_cache = None
-        if not self._sandbox_apt_cache:
+        if not self._sandbox_apt_cache or arch != self._sandbox_apt_cache_arch:
             self._build_apt_sandbox(aptroot, apt_sources, distro_name,
                                     release_codename, origins)
             rootdir = os.path.abspath(aptroot)
             self._sandbox_apt_cache = apt.Cache(rootdir=rootdir)
+            self._sandbox_apt_cache_arch = arch
             try:
                 # We don't need to update this multiple times.
                 self._sandbox_apt_cache.update(fetchProgress)
@@ -669,7 +672,7 @@
     def install_packages(self, rootdir, configdir, release, packages,
                          verbose=False, cache_dir=None,
                          permanent_rootdir=False, architecture=None,
-                         origins=None, install_dbg=True):
+                         origins=None, install_dbg=True, install_deps=False):
         '''Install packages into a sandbox (for apport-retrace).
 
         In order to work without any special permissions and without touching
@@ -701,6 +704,9 @@
         If origins is given, the sandbox will be created with apt data sources
         for foreign origins.
 
+        If install_deps is True, then the dependencies of packages will also
+        be installed.
+
         Return a string with outdated packages, or None if all packages were
         installed.
 
@@ -738,10 +744,14 @@
         # create apt sandbox
         if cache_dir:
             tmp_aptroot = False
+            if architecture != self.get_system_architecture():
+                aptroot_arch = architecture
+            else:
+                aptroot_arch = ''
             if configdir:
-                aptroot = os.path.join(cache_dir, release, 'apt')
+                aptroot = os.path.join(cache_dir, release, aptroot_arch, 'apt')
             else:
-                aptroot = os.path.join(cache_dir, 'system', 'apt')
+                aptroot = os.path.join(cache_dir, 'system', aptroot_arch, 'apt')
             if not os.path.isdir(aptroot):
                 os.makedirs(aptroot)
         else:
@@ -762,7 +772,7 @@
             cache = self._sandbox_cache(aptroot, apt_sources, fetchProgress,
                                         self.get_distro_name(),
                                         self.current_release_codename,
-                                        origins)
+                                        origins, architecture)
         else:
             self._build_apt_sandbox(aptroot, apt_sources,
                                     self.get_distro_name(),
@@ -798,6 +808,38 @@
         fetcher = apt.apt_pkg.Acquire(fetchProgress)
         # need to keep AcquireFile references
         acquire_queue = []
+        # add any dependencies to the packages list
+        if install_deps:
+            deps = []
+            for (pkg, ver) in packages:
+                try:
+                    cache_pkg = cache[pkg]
+                except KeyError:
+                    m = 'package %s does not exist, ignoring' % pkg.replace('%', '%%')
+                    obsolete += m + '\n'
+                    apport.warning(m)
+                    continue
+                for dep in cache_pkg.candidate.dependencies:
+                    # if the dependency is in the list of packages we don't
+                    # need to look up its dependencies again
+                    if dep[0].name in [p[0] for p in packages]:
+                        continue
+                    # if the package is already extracted in the sandbox
+                    # because the report need that package we don't want to
+                    # install a newer version which may cause a CRC mismatch
+                    # with the installed dbg symbols
+                    if dep[0].name in pkg_versions:
+                        inst_version = pkg_versions[dep[0].name]
+                        if self.compare_versions(inst_version, dep[0].version) > -1:
+                            deps.append((dep[0].name, inst_version))
+                        else:
+                            deps.append((dep[0].name, dep[0].version))
+                    else:
+                        deps.append((dep[0].name, dep[0].version))
+                    if dep[0].name not in [p[0] for p in packages]:
+                        packages.append((dep[0].name, None))
+            packages.extend(deps)
+
         for (pkg, ver) in packages:
             try:
                 cache_pkg = cache[pkg]
@@ -1012,9 +1054,9 @@
         if verbose:
             print('Extracting downloaded debs...')
         for i in fetcher.items:
-            if not permanent_rootdir or os.path.getctime(i.destfile) > last_written:
-                out = subprocess.check_output(['dpkg-deb', '--show', i.destfile]).decode()
-                (p, v) = out.strip().split()
+            out = subprocess.check_output(['dpkg-deb', '--show', i.destfile]).decode()
+            (p, v) = out.strip().split()
+            if not permanent_rootdir or p not in pkg_versions or os.path.getctime(i.destfile) > last_written:
                 # don't extract the same version of the package if it is
                 # already extracted
                 if pkg_versions.get(p) == v:

=== modified file 'bin/apport-retrace'
--- bin/apport-retrace	2016-12-18 12:53:35 +0000
+++ bin/apport-retrace	2017-01-25 19:24:04 +0000
@@ -49,6 +49,8 @@
                            help=_('Rebuild report\'s Package information'))
     argparser.add_argument('-S', '--sandbox', metavar='CONFIG_DIR',
                            help=_('Build a temporary sandbox and download/install the necessary packages and debug symbols in there; without this option it assumes that the necessary packages and debug symbols are already installed in the system. The argument points to the packaging system configuration base directory; if you specify "system", it will use the system configuration files, but will then only be able to retrace crashes that happened on the currently running release.'))
+    argparser.add_argument('--gdb-sandbox', action='store_true',
+                           help=_('Build another temporary sandbox for installing gdb and its dependencies using the same release as the report rather than whatever version of gdb you have installed.'))
     argparser.add_argument('-v', '--verbose', action='store_true',
                            help=_('Report download/install progress when installing packages into sandbox'))
     argparser.add_argument('--timestamps', action='store_true',
@@ -280,7 +282,8 @@
 
 
 # sanity checks
-required_fields = set(['CoreDump', 'ExecutablePath', 'Package', 'DistroRelease'])
+required_fields = set(['CoreDump', 'ExecutablePath', 'Package',
+                       'DistroRelease', 'Architecture'])
 if report['ProblemType'] == 'KernelCrash':
     if not set(['Package', 'VmCore']).issubset(set(report.keys())):
         apport.error('report file does not contain the required fields')
@@ -294,18 +297,59 @@
 
 apport.memdbg('sanity checks passed')
 
+if options.gdb_sandbox:
+    system_arch = apport.packaging.get_system_architecture()
+
 if options.sandbox:
+    if options.sandbox_dir:
+        sandbox_dir = '%s/%s/%s/report-sandbox/' % \
+            (options.sandbox_dir, report['DistroRelease'],
+             report['Architecture'])
+    else:
+        sandbox_dir = None
+    if options.gdb_sandbox:
+        if report['Architecture'] == system_arch:
+            options.extra_package.append('gdb')
     sandbox, cache, outdated_msg = apport.sandboxutils.make_sandbox(
-        report, options.sandbox, options.cache, options.sandbox_dir,
+        report, options.sandbox, options.cache, sandbox_dir,
         options.extra_package, options.verbose, log_timestamps,
         options.dynamic_origins)
 else:
     sandbox = None
+    cache = None
     outdated_msg = None
 
+if options.gdb_sandbox:
+    if report['Architecture'] == system_arch:
+        if sandbox:
+            # gdb was installed in the sandbox
+            gdb_sandbox = sandbox
+            gdb_cache = cache
+    else:
+        gdb_packages = ['gdb', 'gdb-multiarch']
+        fake_report = apport.Report()
+        # if the report has no Architecture the host one will be used
+        fake_report['DistroRelease'] = report['DistroRelease']
+        # use a empty ProcMaps so needed_runtimes packages won't want ExecPath
+        fake_report['ProcMaps'] = '\n\n'
+        if options.sandbox_dir:
+            gdb_sandbox_dir = '%s/%s/%s/gdb-sandbox/' % \
+                (options.sandbox_dir, report['DistroRelease'], system_arch)
+        else:
+            gdb_sandbox_dir = None
+        gdb_sandbox, gdb_cache, gdb_outdated_msg = \
+                apport.sandboxutils.make_sandbox(fake_report,
+                    options.sandbox, options.cache, gdb_sandbox_dir,
+                    gdb_packages, options.verbose, log_timestamps,
+                    options.dynamic_origins)
+else:
+    gdb_sandbox = None
+    gdb_cache = None
+    gdb_outdated_msg = None
+
 # interactive gdb session
 if options.gdb:
-    gdb_cmd = report.gdb_command(sandbox)
+    gdb_cmd = report.gdb_command(sandbox, gdb_sandbox)
     if options.verbose:
         # build a shell-style command
         cmd = ''
@@ -318,12 +362,22 @@
                 cmd += w
         apport.log('Calling gdb command: ' + cmd, log_timestamps)
     apport.memdbg('before calling gdb')
+    if options.gdb_sandbox:
+        # save existing env settings
+        orig_ld_lib_path = os.environ.get('LD_LIBRARY_PATH', '')
+        orig_pyhome = os.environ.get('PYTHONHOME', '')
+        orig_gconv_path = os.environ.get('GCONV_PATH', '')
     subprocess.call(gdb_cmd)
+    if options.gdb_sandbox:
+        # restore the env settings
+        os.environ['LD_LIBRARY_PATH'] = orig_ld_lib_path
+        os.environ['PYTHONHOME'] = orig_pyhome
+        os.environ['GCONV_PATH'] = orig_gconv_path
 else:
     # regenerate gdb info
     apport.memdbg('before collecting gdb info')
     try:
-        report.add_gdb_info(sandbox)
+        report.add_gdb_info(sandbox, gdb_sandbox)
     except IOError as e:
         if not options.auth:
             apport.fatal(str(e))

=== modified file 'po/apport.pot'
--- po/apport.pot	2015-09-10 09:17:19 +0000
+++ po/apport.pot	2017-01-25 19:24:04 +0000
@@ -8,7 +8,7 @@
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-09-10 11:16+0200\n"
+"POT-Creation-Date: 2016-12-19 10:06-0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -17,8 +17,8 @@
 "Content-Type: text/plain; charset=CHARSET\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../gtk/apport-gtk.ui.h:1 ../kde/apport-kde.py:468 ../kde/apport-kde.py:503
-#: ../kde/apport-kde.py:522
+#: ../gtk/apport-gtk.ui.h:1 ../kde/apport-kde.py:469 ../kde/apport-kde.py:504
+#: ../kde/apport-kde.py:524
 msgid "Apport"
 msgstr ""
 
@@ -38,7 +38,7 @@
 msgid "<big><b>Sorry, an internal error happened.</b></big>"
 msgstr ""
 
-#: ../gtk/apport-gtk.ui.h:6 ../gtk/apport-gtk.py:300 ../kde/apport-kde.py:240
+#: ../gtk/apport-gtk.ui.h:6 ../gtk/apport-gtk.py:303 ../kde/apport-kde.py:241
 msgid "If you notice further problems, try restarting the computer."
 msgstr ""
 
@@ -50,8 +50,8 @@
 msgid "Ignore future problems of this program version"
 msgstr ""
 
-#: ../gtk/apport-gtk.ui.h:9 ../gtk/apport-gtk.py:204 ../gtk/apport-gtk.py:573
-#: ../kde/apport-kde.py:291
+#: ../gtk/apport-gtk.ui.h:9 ../gtk/apport-gtk.py:207 ../gtk/apport-gtk.py:576
+#: ../kde/apport-kde.py:292
 msgid "Show Details"
 msgstr ""
 
@@ -59,12 +59,12 @@
 msgid "_Examine locally"
 msgstr ""
 
-#: ../gtk/apport-gtk.ui.h:11 ../gtk/apport-gtk.py:287 ../kde/apport-kde.py:233
+#: ../gtk/apport-gtk.ui.h:11 ../gtk/apport-gtk.py:290 ../kde/apport-kde.py:234
 msgid "Leave Closed"
 msgstr ""
 
-#: ../gtk/apport-gtk.ui.h:12 ../gtk/apport-gtk.py:216 ../gtk/apport-gtk.py:284
-#: ../gtk/apport-gtk.py:303 ../kde/apport-kde.py:230 ../kde/apport-kde.py:243
+#: ../gtk/apport-gtk.ui.h:12 ../gtk/apport-gtk.py:219 ../gtk/apport-gtk.py:287
+#: ../gtk/apport-gtk.py:306 ../kde/apport-kde.py:231 ../kde/apport-kde.py:244
 msgid "Continue"
 msgstr ""
 
@@ -78,7 +78,7 @@
 "you report."
 msgstr ""
 
-#: ../gtk/apport-gtk.ui.h:15 ../kde/apport-kde.py:434 ../bin/apport-cli.py:251
+#: ../gtk/apport-gtk.ui.h:15 ../kde/apport-kde.py:435 ../bin/apport-cli.py:251
 msgid "Uploading problem information"
 msgstr ""
 
@@ -86,308 +86,97 @@
 msgid "<big><b>Uploading problem information</b></big>"
 msgstr ""
 
-#: ../gtk/apport-gtk.ui.h:17 ../kde/apport-kde.py:435
+#: ../gtk/apport-gtk.ui.h:17 ../kde/apport-kde.py:436
 msgid ""
 "The collected information is being sent to the bug tracking system. This "
 "might take a few minutes."
 msgstr ""
 
-#: ../kde/apport-kde-mimelnk.desktop.in.h:1
-msgid "Apport crash file"
-msgstr ""
-
-#: ../gtk/apport-gtk.py:142 ../kde/apport-kde.py:362 ../bin/apport-cli.py:150
+#: ../gtk/apport-gtk.py:145 ../kde/apport-kde.py:363 ../bin/apport-cli.py:150
 msgid "(binary data)"
 msgstr ""
 
-#: ../gtk/apport-gtk.py:157
+#: ../gtk/apport-gtk.py:160
 #, python-format
 msgid "Sorry, the application %s has stopped unexpectedly."
 msgstr ""
 
-#: ../gtk/apport-gtk.py:160
+#: ../gtk/apport-gtk.py:163
 #, python-format
 msgid "Sorry, %s has closed unexpectedly."
 msgstr ""
 
-#: ../gtk/apport-gtk.py:165 ../kde/apport-kde.py:199 ../kde/apport-kde.py:237
+#: ../gtk/apport-gtk.py:168 ../kde/apport-kde.py:200 ../kde/apport-kde.py:238
 #, python-format
 msgid "Sorry, %s has experienced an internal error."
 msgstr ""
 
-#: ../gtk/apport-gtk.py:177 ../kde/apport-kde.py:185 ../bin/apport-cli.py:178
+#: ../gtk/apport-gtk.py:180 ../kde/apport-kde.py:186 ../bin/apport-cli.py:178
 msgid "Send problem report to the developers?"
 msgstr ""
 
-#: ../gtk/apport-gtk.py:186 ../kde/apport-kde.py:193
+#: ../gtk/apport-gtk.py:189 ../kde/apport-kde.py:194
 msgid "Send"
 msgstr ""
 
-#: ../gtk/apport-gtk.py:228
+#: ../gtk/apport-gtk.py:231
 msgid "Force Closed"
 msgstr ""
 
-#: ../gtk/apport-gtk.py:229 ../gtk/apport-gtk.py:288 ../kde/apport-kde.py:234
-#: ../kde/apport-kde.py:380
+#: ../gtk/apport-gtk.py:232 ../gtk/apport-gtk.py:291 ../kde/apport-kde.py:235
+#: ../kde/apport-kde.py:381
 msgid "Relaunch"
 msgstr ""
 
-#: ../gtk/apport-gtk.py:238
+#: ../gtk/apport-gtk.py:241
 #, python-format
 msgid "The application %s has stopped responding."
 msgstr ""
 
-#: ../gtk/apport-gtk.py:242
+#: ../gtk/apport-gtk.py:245
 #, python-format
 msgid "The program \"%s\" has stopped responding."
 msgstr ""
 
-#: ../gtk/apport-gtk.py:257 ../kde/apport-kde.py:207
+#: ../gtk/apport-gtk.py:260 ../kde/apport-kde.py:208
 #, python-format
 msgid "Package: %s"
 msgstr ""
 
-#: ../gtk/apport-gtk.py:264 ../kde/apport-kde.py:213
+#: ../gtk/apport-gtk.py:267 ../kde/apport-kde.py:214
 msgid "Sorry, a problem occurred while installing software."
 msgstr ""
 
-#: ../gtk/apport-gtk.py:273 ../gtk/apport-gtk.py:292 ../kde/apport-kde.py:219
+#: ../gtk/apport-gtk.py:276 ../gtk/apport-gtk.py:295 ../kde/apport-kde.py:220
 #, python-format
 msgid "The application %s has experienced an internal error."
 msgstr ""
 
-#: ../gtk/apport-gtk.py:276 ../kde/apport-kde.py:222
+#: ../gtk/apport-gtk.py:279 ../kde/apport-kde.py:223
 #, python-format
 msgid "The application %s has closed unexpectedly."
 msgstr ""
 
-#: ../gtk/apport-gtk.py:304 ../kde/apport-kde.py:244
+#: ../gtk/apport-gtk.py:307 ../kde/apport-kde.py:245
 msgid "Ignore future problems of this type"
 msgstr ""
 
-#: ../gtk/apport-gtk.py:577 ../kde/apport-kde.py:288
+#: ../gtk/apport-gtk.py:580 ../kde/apport-kde.py:289
 msgid "Hide Details"
 msgstr ""
 
-#: ../bin/apport-unpack.py:22
-#, python-format
-msgid "Usage: %s <report> <target directory>"
-msgstr ""
-
-#: ../bin/apport-unpack.py:46
-msgid "Destination directory exists and is not empty."
-msgstr ""
-
-#: ../kde/apport-kde.py:314
-msgid "Username:"
-msgstr ""
-
-#: ../kde/apport-kde.py:315
-msgid "Password:"
-msgstr ""
-
-#: ../kde/apport-kde.py:405
-msgid "Collecting Problem Information"
-msgstr ""
-
-#: ../kde/apport-kde.py:406 ../bin/apport-cli.py:238
-msgid "Collecting problem information"
-msgstr ""
-
-#: ../kde/apport-kde.py:407
-msgid ""
-"The collected information can be sent to the developers to improve the "
-"application. This might take a few minutes."
-msgstr ""
-
-#: ../kde/apport-kde.py:433
-msgid "Uploading Problem Information"
-msgstr ""
-
-#: ../apport/com.ubuntu.apport.policy.in.h:1
-msgid "Collect system information"
-msgstr ""
-
-#: ../apport/com.ubuntu.apport.policy.in.h:2
-msgid ""
-"Authentication is required to collect system information for this problem "
-"report"
-msgstr ""
-
-#: ../apport/com.ubuntu.apport.policy.in.h:3
-msgid "System problem reports"
-msgstr ""
-
-#: ../apport/com.ubuntu.apport.policy.in.h:4
-msgid "Please enter your password to access problem reports of system programs"
-msgstr ""
-
-#: ../kde/apport-kde.desktop.in.h:1 ../gtk/apport-gtk.desktop.in.h:1
-#: ../kde/apport-kde-mime.desktop.in.h:1
-msgid "Report a problem..."
-msgstr ""
-
-#: ../kde/apport-kde.desktop.in.h:2 ../gtk/apport-gtk.desktop.in.h:2
-#: ../kde/apport-kde-mime.desktop.in.h:2
-msgid "Report a malfunction to the developers"
-msgstr ""
-
-#: ../bin/apport-valgrind.py:37
-msgid "See man page for details."
-msgstr ""
-
-#: ../bin/apport-valgrind.py:43
-msgid "specify the log file name produced by valgrind"
-msgstr ""
-
-#: ../bin/apport-valgrind.py:46
-msgid ""
-"reuse a previously created sandbox dir (SDIR) or, if it does not exist, "
-"create it"
-msgstr ""
-
-#: ../bin/apport-valgrind.py:50
-msgid ""
-"do  not  create  or reuse a sandbox directory for additional debug symbols "
-"but rely only on installed debug symbols."
-msgstr ""
-
-#: ../bin/apport-valgrind.py:54
-msgid ""
-"reuse a previously created cache dir (CDIR) or, if it does not exist, create "
-"it"
-msgstr ""
-
-#: ../bin/apport-valgrind.py:58
-msgid "report download/install progress when installing packages into sandbox"
-msgstr ""
-
-#: ../bin/apport-valgrind.py:62
-msgid ""
-"the executable that is run under valgrind's memcheck tool  for memory leak "
-"detection"
-msgstr ""
-
-#: ../bin/apport-valgrind.py:66 ../bin/apport-retrace.py:63
-msgid ""
-"Install an extra package into the sandbox (can be specified multiple times)"
-msgstr ""
-
-#: ../bin/apport-valgrind.py:97
-#, python-format
-msgid "Error: %s is not an executable. Stopping."
-msgstr ""
-
-#: ../data/kernel_oops.py:29
-msgid "Your system might become unstable now and might need to be restarted."
-msgstr ""
-
-#: ../bin/apport-retrace.py:34
-msgid "Do not put the new traces into the report, but write them to stdout."
-msgstr ""
-
-#: ../bin/apport-retrace.py:36
-msgid ""
-"Start an interactive gdb session with the report's core dump (-o ignored; "
-"does not rewrite report)"
-msgstr ""
-
-#: ../bin/apport-retrace.py:38
-msgid ""
-"Write modified report to given file instead of changing the original report"
-msgstr ""
-
-#: ../bin/apport-retrace.py:41
-msgid "Remove the core dump from the report after stack trace regeneration"
-msgstr ""
-
-#: ../bin/apport-retrace.py:43
-msgid "Override report's CoreFile"
-msgstr ""
-
-#: ../bin/apport-retrace.py:45
-msgid "Override report's ExecutablePath"
-msgstr ""
-
-#: ../bin/apport-retrace.py:47
-msgid "Override report's ProcMaps"
-msgstr ""
-
-#: ../bin/apport-retrace.py:49
-msgid "Rebuild report's Package information"
-msgstr ""
-
-#: ../bin/apport-retrace.py:51
-msgid ""
-"Build a temporary sandbox and download/install the necessary packages and "
-"debug symbols in there; without this option it assumes that the necessary "
-"packages and debug symbols are already installed in the system. The argument "
-"points to the packaging system configuration base directory; if you specify "
-"\"system\", it will use the system configuration files, but will then only "
-"be able to retrace crashes that happened on the currently running release."
-msgstr ""
-
-#: ../bin/apport-retrace.py:53
-msgid "Report download/install progress when installing packages into sandbox"
-msgstr ""
-
-#: ../bin/apport-retrace.py:55
-msgid "Prepend timestamps to log messages, for batch operation"
-msgstr ""
-
-#: ../bin/apport-retrace.py:57
-msgid ""
-"Create and use third-party repositories from origins specified in reports"
-msgstr ""
-
-#: ../bin/apport-retrace.py:59
-msgid "Cache directory for packages downloaded in the sandbox"
-msgstr ""
-
-#: ../bin/apport-retrace.py:61
-msgid ""
-"Directory for unpacked packages. Future runs will assume that any already "
-"downloaded package is also extracted to this sandbox."
-msgstr ""
-
-#: ../bin/apport-retrace.py:65
-msgid ""
-"Path to a file with the crash database authentication information. This is "
-"used when specifying a crash ID to upload the retraced stack traces (only if "
-"neither -g, -o, nor -s are specified)"
-msgstr ""
-
-#: ../bin/apport-retrace.py:67
-msgid ""
-"Display retraced stack traces and ask for confirmation before sending them "
-"to the crash database."
-msgstr ""
-
-#: ../bin/apport-retrace.py:69
-msgid "Path to the duplicate sqlite database (default: no duplicate checking)"
-msgstr ""
-
-#: ../bin/apport-retrace.py:78
-msgid "You cannot use -C without -S. Stopping."
-msgstr ""
-
-#. translators: don't translate y/n, apport currently only checks for "y"
-#: ../bin/apport-retrace.py:111
-msgid "OK to send these as attachments? [y/n]"
-msgstr ""
-
-#: ../apport/ui.py:124
+#: ../apport/ui.py:131
 msgid "This package does not seem to be installed correctly"
 msgstr ""
 
-#: ../apport/ui.py:129
+#: ../apport/ui.py:136
 #, python-format
 msgid ""
 "This is not an official %s package. Please remove any third party package "
 "and try again."
 msgstr ""
 
-#: ../apport/ui.py:146
+#: ../apport/ui.py:153
 #, python-format
 msgid ""
 "You have some obsolete package versions installed. Please upgrade the "
@@ -396,90 +185,90 @@
 "%s"
 msgstr ""
 
-#: ../apport/ui.py:270
+#: ../apport/ui.py:281
 msgid "unknown program"
 msgstr ""
 
-#: ../apport/ui.py:271
+#: ../apport/ui.py:282
 #, python-format
 msgid "Sorry, the program \"%s\" closed unexpectedly"
 msgstr ""
 
-#: ../apport/ui.py:273 ../apport/ui.py:1301
+#: ../apport/ui.py:284 ../apport/ui.py:1312
 #, python-format
 msgid "Problem in %s"
 msgstr ""
 
-#: ../apport/ui.py:274
+#: ../apport/ui.py:285
 msgid ""
 "Your computer does not have enough free memory to automatically analyze the "
 "problem and send a report to the developers."
 msgstr ""
 
-#: ../apport/ui.py:317 ../apport/ui.py:325 ../apport/ui.py:452
-#: ../apport/ui.py:455 ../apport/ui.py:656 ../apport/ui.py:1107
-#: ../apport/ui.py:1273 ../apport/ui.py:1277
+#: ../apport/ui.py:328 ../apport/ui.py:336 ../apport/ui.py:463
+#: ../apport/ui.py:466 ../apport/ui.py:667 ../apport/ui.py:1118
+#: ../apport/ui.py:1284 ../apport/ui.py:1288
 msgid "Invalid problem report"
 msgstr ""
 
-#: ../apport/ui.py:318
+#: ../apport/ui.py:329
 msgid "You are not allowed to access this problem report."
 msgstr ""
 
-#: ../apport/ui.py:321
+#: ../apport/ui.py:332
 msgid "Error"
 msgstr ""
 
-#: ../apport/ui.py:322
+#: ../apport/ui.py:333
 msgid "There is not enough disk space available to process this report."
 msgstr ""
 
-#: ../apport/ui.py:406
+#: ../apport/ui.py:417
 msgid "No package specified"
 msgstr ""
 
-#: ../apport/ui.py:407
+#: ../apport/ui.py:418
 msgid ""
 "You need to specify a package or a PID. See --help for more information."
 msgstr ""
 
-#: ../apport/ui.py:430
+#: ../apport/ui.py:441
 msgid "Permission denied"
 msgstr ""
 
-#: ../apport/ui.py:431
+#: ../apport/ui.py:442
 msgid ""
 "The specified process does not belong to you. Please run this program as the "
 "process owner or as root."
 msgstr ""
 
-#: ../apport/ui.py:433
+#: ../apport/ui.py:444
 msgid "Invalid PID"
 msgstr ""
 
-#: ../apport/ui.py:434
+#: ../apport/ui.py:445
 msgid "The specified process ID does not belong to a program."
 msgstr ""
 
-#: ../apport/ui.py:453
+#: ../apport/ui.py:464
 #, python-format
 msgid "Symptom script %s did not determine an affected package"
 msgstr ""
 
-#: ../apport/ui.py:456
+#: ../apport/ui.py:467
 #, python-format
 msgid "Package %s does not exist"
 msgstr ""
 
-#: ../apport/ui.py:480 ../apport/ui.py:668 ../apport/ui.py:673
+#: ../apport/ui.py:491 ../apport/ui.py:679 ../apport/ui.py:684
 msgid "Cannot create report"
 msgstr ""
 
-#: ../apport/ui.py:495 ../apport/ui.py:541 ../apport/ui.py:558
+#: ../apport/ui.py:506 ../apport/ui.py:552 ../apport/ui.py:569
 msgid "Updating problem report"
 msgstr ""
 
-#: ../apport/ui.py:496
+#: ../apport/ui.py:507
 msgid ""
 "You are not the reporter or subscriber of this problem report, or the report "
 "is a duplicate or already closed.\n"
@@ -487,7 +276,7 @@
 "Please create a new report using \"apport-bug\"."
 msgstr ""
 
-#: ../apport/ui.py:505
+#: ../apport/ui.py:516
 msgid ""
 "You are not the reporter of this problem report. It is much easier to mark a "
 "bug as a duplicate of another than to move your comments and attachments to "
@@ -499,185 +288,185 @@
 "Do you really want to proceed?"
 msgstr ""
 
-#: ../apport/ui.py:542 ../apport/ui.py:559
+#: ../apport/ui.py:553 ../apport/ui.py:570
 msgid "No additional information collected."
 msgstr ""
 
-#: ../apport/ui.py:610
+#: ../apport/ui.py:621
 msgid "What kind of problem do you want to report?"
 msgstr ""
 
-#: ../apport/ui.py:627
+#: ../apport/ui.py:638
 msgid "Unknown symptom"
 msgstr ""
 
-#: ../apport/ui.py:628
+#: ../apport/ui.py:639
 #, python-format
 msgid "The symptom \"%s\" is not known."
 msgstr ""
 
-#: ../apport/ui.py:659
+#: ../apport/ui.py:670
 msgid ""
 "After closing this message please click on an application window to report a "
 "problem about it."
 msgstr ""
 
-#: ../apport/ui.py:669 ../apport/ui.py:674
+#: ../apport/ui.py:680 ../apport/ui.py:685
 msgid "xprop failed to determine process ID of the window"
 msgstr ""
 
-#: ../apport/ui.py:688
+#: ../apport/ui.py:699
 msgid "%prog <report number>"
 msgstr ""
 
-#: ../apport/ui.py:690
+#: ../apport/ui.py:701
 msgid "Specify package name."
 msgstr ""
 
-#: ../apport/ui.py:692 ../apport/ui.py:743
+#: ../apport/ui.py:703 ../apport/ui.py:754
 msgid "Add an extra tag to the report. Can be specified multiple times."
 msgstr ""
 
-#: ../apport/ui.py:722
+#: ../apport/ui.py:733
 msgid "%prog [options] [symptom|pid|package|program path|.apport/.crash file]"
 msgstr ""
 
-#: ../apport/ui.py:725
+#: ../apport/ui.py:736
 msgid ""
 "Start in bug filing mode. Requires --package and an optional --pid, or just "
 "a --pid. If neither is given, display a list of known symptoms. (Implied if "
 "a single argument is given.)"
 msgstr ""
 
-#: ../apport/ui.py:727
+#: ../apport/ui.py:738
 msgid "Click a window as a target for filing a problem report."
 msgstr ""
 
-#: ../apport/ui.py:729
+#: ../apport/ui.py:740
 msgid "Start in bug updating mode. Can take an optional --package."
 msgstr ""
 
-#: ../apport/ui.py:731
+#: ../apport/ui.py:742
 msgid ""
 "File a bug report about a symptom. (Implied if symptom name is given as only "
 "argument.)"
 msgstr ""
 
-#: ../apport/ui.py:733
+#: ../apport/ui.py:744
 msgid ""
 "Specify package name in --file-bug mode. This is optional if a --pid is "
 "specified. (Implied if package name is given as only argument.)"
 msgstr ""
 
-#: ../apport/ui.py:735
+#: ../apport/ui.py:746
 msgid ""
 "Specify a running program in --file-bug mode. If this is specified, the bug "
 "report will contain more information.  (Implied if pid is given as only "
 "argument.)"
 msgstr ""
 
-#: ../apport/ui.py:737
+#: ../apport/ui.py:748
 msgid "The provided pid is a hanging application."
 msgstr ""
 
-#: ../apport/ui.py:739
+#: ../apport/ui.py:750
 #, python-format
 msgid ""
 "Report the crash from given .apport or .crash file instead of the pending "
 "ones in %s. (Implied if file is given as only argument.)"
 msgstr ""
 
-#: ../apport/ui.py:741
+#: ../apport/ui.py:752
 msgid ""
 "In bug filing mode, save the collected information into a file instead of "
 "reporting it. This file can then be reported later on from a different "
 "machine."
 msgstr ""
 
-#: ../apport/ui.py:745
+#: ../apport/ui.py:756
 msgid "Print the Apport version number."
 msgstr ""
 
-#: ../apport/ui.py:884
+#: ../apport/ui.py:895
 msgid ""
 "This will launch apport-retrace in a terminal window to examine the crash."
 msgstr ""
 
-#: ../apport/ui.py:885
+#: ../apport/ui.py:896
 msgid "Run gdb session"
 msgstr ""
 
-#: ../apport/ui.py:886
+#: ../apport/ui.py:897
 msgid "Run gdb session without downloading debug symbols"
 msgstr ""
 
 #. TRANSLATORS: %s contains the crash report file name
-#: ../apport/ui.py:888
+#: ../apport/ui.py:899
 #, python-format
 msgid "Update %s with fully symbolic stack trace"
 msgstr ""
 
-#: ../apport/ui.py:962 ../apport/ui.py:972
+#: ../apport/ui.py:973 ../apport/ui.py:983
 msgid ""
 "This problem report applies to a program which is not installed any more."
 msgstr ""
 
-#: ../apport/ui.py:986
+#: ../apport/ui.py:997
 #, python-format
 msgid ""
 "The problem happened with the program %s which changed since the crash "
 "occurred."
 msgstr ""
 
-#: ../apport/ui.py:1033 ../apport/ui.py:1064 ../apport/ui.py:1279
+#: ../apport/ui.py:1044 ../apport/ui.py:1075 ../apport/ui.py:1290
 msgid "This problem report is damaged and cannot be processed."
 msgstr ""
 
 #. package does not exist
-#: ../apport/ui.py:1036
+#: ../apport/ui.py:1047
 msgid "The report belongs to a package that is not installed."
 msgstr ""
 
-#: ../apport/ui.py:1039
+#: ../apport/ui.py:1050
 msgid "An error occurred while attempting to process this problem report:"
 msgstr ""
 
-#: ../apport/ui.py:1108
+#: ../apport/ui.py:1119
 msgid "Could not determine the package or source package name."
 msgstr ""
 
-#: ../apport/ui.py:1126
+#: ../apport/ui.py:1137
 msgid "Unable to start web browser"
 msgstr ""
 
-#: ../apport/ui.py:1127
+#: ../apport/ui.py:1138
 #, python-format
 msgid "Unable to start web browser to open %s."
 msgstr ""
 
-#: ../apport/ui.py:1227
+#: ../apport/ui.py:1238
 #, python-format
 msgid "Please enter your account information for the %s bug tracking system"
 msgstr ""
 
-#: ../apport/ui.py:1239
+#: ../apport/ui.py:1250
 msgid "Network problem"
 msgstr ""
 
-#: ../apport/ui.py:1241
+#: ../apport/ui.py:1252
 msgid ""
 "Cannot connect to crash database, please check your Internet connection."
 msgstr ""
 
-#: ../apport/ui.py:1268
+#: ../apport/ui.py:1279
 msgid "Memory exhaustion"
 msgstr ""
 
-#: ../apport/ui.py:1269
+#: ../apport/ui.py:1280
 msgid "Your system does not have enough memory to process this crash report."
 msgstr ""
 
-#: ../apport/ui.py:1304
+#: ../apport/ui.py:1315
 #, python-format
 msgid ""
 "The problem cannot be reported:\n"
@@ -685,21 +474,201 @@
 "%s"
 msgstr ""
 
-#: ../apport/ui.py:1360 ../apport/ui.py:1367
+#: ../apport/ui.py:1371 ../apport/ui.py:1378
 msgid "Problem already known"
 msgstr ""
 
-#: ../apport/ui.py:1361
+#: ../apport/ui.py:1372
 msgid ""
 "This problem was already reported in the bug report displayed in the web "
 "browser. Please check if you can add any further information that might be "
 "helpful for the developers."
 msgstr ""
 
-#: ../apport/ui.py:1368
+#: ../apport/ui.py:1379
 msgid "This problem was already reported to developers. Thank you!"
 msgstr ""
 
+#: ../kde/apport-kde.desktop.in.h:1 ../kde/apport-kde-mime.desktop.in.h:1
+#: ../gtk/apport-gtk.desktop.in.h:1
+msgid "Report a problem..."
+msgstr ""
+
+#: ../kde/apport-kde.desktop.in.h:2 ../kde/apport-kde-mime.desktop.in.h:2
+#: ../gtk/apport-gtk.desktop.in.h:2
+msgid "Report a malfunction to the developers"
+msgstr ""
+
+#: ../bin/apport-retrace.py:34
+msgid "Do not put the new traces into the report, but write them to stdout."
+msgstr ""
+
+#: ../bin/apport-retrace.py:36
+msgid ""
+"Start an interactive gdb session with the report's core dump (-o ignored; "
+"does not rewrite report)"
+msgstr ""
+
+#: ../bin/apport-retrace.py:38
+msgid ""
+"Write modified report to given file instead of changing the original report"
+msgstr ""
+
+#: ../bin/apport-retrace.py:41
+msgid "Remove the core dump from the report after stack trace regeneration"
+msgstr ""
+
+#: ../bin/apport-retrace.py:43
+msgid "Override report's CoreFile"
+msgstr ""
+
+#: ../bin/apport-retrace.py:45
+msgid "Override report's ExecutablePath"
+msgstr ""
+
+#: ../bin/apport-retrace.py:47
+msgid "Override report's ProcMaps"
+msgstr ""
+
+#: ../bin/apport-retrace.py:49
+msgid "Rebuild report's Package information"
+msgstr ""
+
+#: ../bin/apport-retrace.py:51
+msgid ""
+"Build a temporary sandbox and download/install the necessary packages and "
+"debug symbols in there; without this option it assumes that the necessary "
+"packages and debug symbols are already installed in the system. The argument "
+"points to the packaging system configuration base directory; if you specify "
+"\"system\", it will use the system configuration files, but will then only "
+"be able to retrace crashes that happened on the currently running release."
+msgstr ""
+
+#: ../bin/apport-retrace.py:53
+msgid "Report download/install progress when installing packages into sandbox"
+msgstr ""
+
+#: ../bin/apport-retrace.py:55
+msgid "Prepend timestamps to log messages, for batch operation"
+msgstr ""
+
+#: ../bin/apport-retrace.py:57
+msgid ""
+"Create and use third-party repositories from origins specified in reports"
+msgstr ""
+
+#: ../bin/apport-retrace.py:59
+msgid "Cache directory for packages downloaded in the sandbox"
+msgstr ""
+
+#: ../bin/apport-retrace.py:61
+msgid ""
+"Directory for unpacked packages. Future runs will assume that any already "
+"downloaded package is also extracted to this sandbox."
+msgstr ""
+
+#: ../bin/apport-retrace.py:63 ../bin/apport-valgrind.py:66
+msgid ""
+"Install an extra package into the sandbox (can be specified multiple times)"
+msgstr ""
+
+#: ../bin/apport-retrace.py:65
+msgid ""
+"Path to a file with the crash database authentication information. This is "
+"used when specifying a crash ID to upload the retraced stack traces (only if "
+"neither -g, -o, nor -s are specified)"
+msgstr ""
+
+#: ../bin/apport-retrace.py:67
+msgid ""
+"Display retraced stack traces and ask for confirmation before sending them "
+"to the crash database."
+msgstr ""
+
+#: ../bin/apport-retrace.py:69
+msgid "Path to the duplicate sqlite database (default: no duplicate checking)"
+msgstr ""
+
+#: ../bin/apport-retrace.py:78
+msgid "You cannot use -C without -S. Stopping."
+msgstr ""
+
+#. translators: don't translate y/n, apport currently only checks for "y"
+#: ../bin/apport-retrace.py:111
+msgid "OK to send these as attachments? [y/n]"
+msgstr ""
+
+#: ../data/kernel_oops.py:29
+msgid "Your system might become unstable now and might need to be restarted."
+msgstr ""
+
+#: ../kde/apport-kde.py:315
+msgid "Username:"
+msgstr ""
+
+#: ../kde/apport-kde.py:316
+msgid "Password:"
+msgstr ""
+
+#: ../kde/apport-kde.py:406
+msgid "Collecting Problem Information"
+msgstr ""
+
+#: ../kde/apport-kde.py:407 ../bin/apport-cli.py:238
+msgid "Collecting problem information"
+msgstr ""
+
+#: ../kde/apport-kde.py:408
+msgid ""
+"The collected information can be sent to the developers to improve the "
+"application. This might take a few minutes."
+msgstr ""
+
+#: ../kde/apport-kde.py:434
+msgid "Uploading Problem Information"
+msgstr ""
+
+#: ../bin/apport-valgrind.py:37
+msgid "See man page for details."
+msgstr ""
+
+#: ../bin/apport-valgrind.py:43
+msgid "specify the log file name produced by valgrind"
+msgstr ""
+
+#: ../bin/apport-valgrind.py:46
+msgid ""
+"reuse a previously created sandbox dir (SDIR) or, if it does not exist, "
+"create it"
+msgstr ""
+
+#: ../bin/apport-valgrind.py:50
+msgid ""
+"do  not  create  or reuse a sandbox directory for additional debug symbols "
+"but rely only on installed debug symbols."
+msgstr ""
+
+#: ../bin/apport-valgrind.py:54
+msgid ""
+"reuse a previously created cache dir (CDIR) or, if it does not exist, create "
+"it"
+msgstr ""
+
+#: ../bin/apport-valgrind.py:58
+msgid "report download/install progress when installing packages into sandbox"
+msgstr ""
+
+#: ../bin/apport-valgrind.py:62
+msgid ""
+"the executable that is run under valgrind's memcheck tool  for memory leak "
+"detection"
+msgstr ""
+
+#: ../bin/apport-valgrind.py:97
+#, python-format
+msgid "Error: %s is not an executable. Stopping."
+msgstr ""
+
 #: ../data/apportcheckresume.py:67
 msgid ""
 "This occurred during a previous suspend, and prevented the system from "
@@ -718,6 +687,33 @@
 "completed normally."
 msgstr ""
 
+#: ../apport/com.ubuntu.apport.policy.in.h:1
+msgid "Collect system information"
+msgstr ""
+
+#: ../apport/com.ubuntu.apport.policy.in.h:2
+msgid ""
+"Authentication is required to collect system information for this problem "
+"report"
+msgstr ""
+
+#: ../apport/com.ubuntu.apport.policy.in.h:3
+msgid "System problem reports"
+msgstr ""
+
+#: ../apport/com.ubuntu.apport.policy.in.h:4
+msgid "Please enter your password to access problem reports of system programs"
+msgstr ""
+
+#: ../bin/apport-unpack.py:22
+#, python-format
+msgid "Usage: %s <report> <target directory>"
+msgstr ""
+
+#: ../bin/apport-unpack.py:47
+msgid "Destination directory exists and is not empty."
+msgstr ""
+
 #: ../bin/apport-cli.py:74
 msgid "Press any key to continue..."
 msgstr ""
@@ -836,6 +832,10 @@
 msgid "Launch a browser now"
 msgstr ""
 
-#: ../bin/apport-cli.py:371
+#: ../bin/apport-cli.py:372
 msgid "No pending crash reports. Try --help for more information."
 msgstr ""
+
+#: ../kde/apport-kde-mimelnk.desktop.in.h:1
+msgid "Apport crash file"
+msgstr ""


Follow ups