[pypy-commit] pypy default: merge the branch keep-debug-symbols:
antocuni
pypy.commits at gmail.com
Wed Nov 1 05:52:54 EDT 2017
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch:
Changeset: r92895:77fff565d382
Date: 2017-11-01 10:51 +0100
http://bitbucket.org/pypy/pypy/changeset/77fff565d382/
Log: merge the branch keep-debug-symbols:
- symbols are stripped from the executable and placed in a file
libpypy-c.so.debug
- we add a gnu-debug-link section to libpypy-c.so which points to
.debug, so that it works transparently in gdb
- this generates immensely more useful stack trace inside gdb;
moreover, it is also potentially usable by vmprof
- the .debug file is ~18MB. The tarball size goes from 22MB to 25MB.
I claim that disk space and bandwidth are cheap, so we should just
don't care, especially for nightly builds
- if we REALLY care about the tarball size of official releases, we
can simply remove the .debug from the tarball
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -21,6 +21,7 @@
import fnmatch
import subprocess
import glob
+from pypy.tool.release.smartstrip import smartstrip
if sys.version_info < (2,6): py.test.skip("requires 2.6 so far")
@@ -212,15 +213,8 @@
old_dir = os.getcwd()
try:
os.chdir(str(builddir))
- if not options.nostrip:
- for source, target in binaries:
- if sys.platform == 'win32':
- pass
- elif sys.platform == 'darwin':
- # 'strip' fun: see issue #587 for why -x
- os.system("strip -x " + str(bindir.join(target))) # ignore errors
- else:
- os.system("strip " + str(bindir.join(target))) # ignore errors
+ for source, target in binaries:
+ smartstrip(bindir.join(target), keep_debug=options.keep_debug)
#
if USE_ZIPFILE_MODULE:
import zipfile
@@ -281,8 +275,8 @@
help='do not build and package the %r cffi module' % (key,))
parser.add_argument('--without-cffi', dest='no_cffi', action='store_true',
help='skip building *all* the cffi modules listed above')
- parser.add_argument('--nostrip', dest='nostrip', action='store_true',
- help='do not strip the exe, making it ~10MB larger')
+ parser.add_argument('--no-keep-debug', dest='keep_debug',
+ action='store_false', help='do not keep debug symbols')
parser.add_argument('--rename_pypy_c', dest='pypy_c', type=str, default=pypy_exe,
help='target executable name, defaults to "pypy"')
parser.add_argument('--archive-name', dest='name', type=str, default='',
@@ -295,8 +289,8 @@
help='use as pypy exe instead of pypy/goal/pypy-c')
options = parser.parse_args(args)
- if os.environ.has_key("PYPY_PACKAGE_NOSTRIP"):
- options.nostrip = True
+ if os.environ.has_key("PYPY_PACKAGE_NOKEEPDEBUG"):
+ options.keep_debug = False
if os.environ.has_key("PYPY_PACKAGE_WITHOUTTK"):
options.no_tk = True
if not options.builddir:
diff --git a/pypy/tool/release/smartstrip.py b/pypy/tool/release/smartstrip.py
new file mode 100644
--- /dev/null
+++ b/pypy/tool/release/smartstrip.py
@@ -0,0 +1,32 @@
+"""
+Strip symbols from an executable, but keep them in a .debug file
+"""
+
+import sys
+import os
+import py
+
+def _strip(exe):
+ if sys.platform == 'win32':
+ pass
+ elif sys.platform == 'darwin':
+ # 'strip' fun: see issue #587 for why -x
+ os.system("strip -x " + str(exe)) # ignore errors
+ else:
+ os.system("strip " + str(exe)) # ignore errors
+
+def _extract_debug_symbols(exe, debug):
+ if sys.platform == 'linux2':
+ os.system("objcopy --only-keep-debug %s %s" % (exe, debug))
+ os.system("objcopy --add-gnu-debuglink=%s %s" % (debug, exe))
+
+def smartstrip(exe, keep_debug=True):
+ exe = py.path.local(exe)
+ debug = py.path.local(str(exe) + '.debug')
+ if keep_debug:
+ _extract_debug_symbols(exe, debug)
+ _strip(exe)
+
+
+if __name__ == '__main__':
+ smartstrip(sys.argv[1])
diff --git a/pypy/tool/release/test/test_smartstrip.py b/pypy/tool/release/test/test_smartstrip.py
new file mode 100644
--- /dev/null
+++ b/pypy/tool/release/test/test_smartstrip.py
@@ -0,0 +1,50 @@
+import pytest
+import sys
+import os
+from commands import getoutput
+from pypy.tool.release.smartstrip import smartstrip
+
+ at pytest.fixture
+def exe(tmpdir):
+ src = tmpdir.join("myprog.c")
+ src.write("""
+ int foo(int a, int b) {
+ return a+b;
+ }
+ int main(void) { }
+ """)
+ exe = tmpdir.join("myprog")
+ ret = os.system("gcc -o %s %s" % (exe, src))
+ assert ret == 0
+ return exe
+
+def info_symbol(exe, symbol):
+ out = getoutput("gdb %s -ex 'info symbol %s' -ex 'quit'" % (exe, symbol))
+ lines = out.splitlines()
+ return lines[-1]
+
+ at pytest.mark.skipif(sys.platform == 'win32',
+ reason='strip not supported on windows')
+class TestSmarStrip(object):
+
+ def test_info_symbol(self, exe):
+ info = info_symbol(exe, "foo")
+ assert info == "foo in section .text"
+
+ def test_strip(self, exe):
+ smartstrip(exe, keep_debug=False)
+ info = info_symbol(exe, "foo")
+ assert info.startswith("No symbol table is loaded")
+
+ @pytest.mark.skipif(sys.platform != 'linux2',
+ reason='keep_debug not supported')
+ def test_keep_debug(self, exe, tmpdir):
+ smartstrip(exe, keep_debug=True)
+ debug = tmpdir.join("myprog.debug")
+ assert debug.check(file=True)
+ info = info_symbol(exe, "foo")
+ assert info == "foo in section .text of %s" % exe
+ #
+ debug.remove()
+ info = info_symbol(exe, "foo")
+ assert info.startswith("No symbol table is loaded")
More information about the pypy-commit
mailing list