Message ID | 20231205133754.906479-1-ecordonnier@snap.com |
---|---|
State | Accepted, archived |
Commit | 0d2df803bebfd7e832ab7da54c4dacaaeeb424a9 |
Headers | show |
Series | [v2] gdb/systemd: enable minidebuginfo support conditionally | expand |
Version 2 of the patch: I implemented the feedback of Richard (convert PACKAGE_MINIDEBUGINFO to a DISTRO_FEATURES), and added a runtime test. This was my local.conf used for testing (with "bitbake -v -c testimage core-image-sato"): DISTRO_FEATURES:append = " minidebuginfo" IMAGE_CLASSES += "testimage" TEST_SUITES += "ping ssh systemd" DISTRO_FEATURES:append = " systemd usrmerge" DISTRO_FEATURES_BACKFILL_CONSIDERED += "sysvinit" VIRTUAL-RUNTIME_init_manager = "systemd" VIRTUAL-RUNTIME_initscripts = "systemd-compat-units" Etienne On Tue, Dec 5, 2023 at 2:38 PM <ecordonnier@snap.com> wrote: > From: Etienne Cordonnier <ecordonnier@snap.com> > > Enabling minidebuginfo is not useful if gdb and systemd-coredump > are unable to parse it. > > In order to parse it, gdb needs xz support. Systemd needs coredump > enabled, as > well as elfutil enabled as well (systemd-coredump loads libdw which is > part of elfutils using dlopen). > > Signed-off-by: Etienne Cordonnier <ecordonnier@snap.com> > --- > meta/classes-global/package.bbclass | 2 +- > meta/lib/oe/package.py | 2 +- > meta/lib/oeqa/runtime/cases/systemd.py | 21 +++++++++++++++++++ > meta/lib/oeqa/selftest/cases/minidebuginfo.py | 2 +- > meta/recipes-core/systemd/systemd_254.4.bb | 1 + > .../elfutils/elfutils_0.189.bb | 4 +++- > meta/recipes-devtools/gdb/gdb-common.inc | 4 +++- > 7 files changed, 31 insertions(+), 5 deletions(-) > > diff --git a/meta/classes-global/package.bbclass > b/meta/classes-global/package.bbclass > index 2ad820a81f..f56bca3542 100644 > --- a/meta/classes-global/package.bbclass > +++ b/meta/classes-global/package.bbclass > @@ -234,7 +234,7 @@ python () { > deps = "" > for dep in (d.getVar('PACKAGE_DEPENDS') or "").split(): > deps += " %s:do_populate_sysroot" % dep > - if d.getVar('PACKAGE_MINIDEBUGINFO') == '1': > + if bb.utils.contains('DISTRO_FEATURES', 'minidebuginfo', True, > False, d): > deps += ' xz-native:do_populate_sysroot' > d.appendVarFlag('do_package', 'depends', deps) > > diff --git a/meta/lib/oe/package.py b/meta/lib/oe/package.py > index f69bf9c353..9a465eaa09 100644 > --- a/meta/lib/oe/package.py > +++ b/meta/lib/oe/package.py > @@ -1239,7 +1239,7 @@ def process_split_and_strip_files(d): > oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d) > > # Build "minidebuginfo" and reinject it back into the stripped > binaries > - if d.getVar('PACKAGE_MINIDEBUGINFO') == '1': > + if bb.utils.contains('DISTRO_FEATURES', 'minidebuginfo', True, False, > d): > oe.utils.multiprocess_launch(inject_minidebuginfo, > list(elffiles), d, > extraargs=(dvar, dv, d)) > > diff --git a/meta/lib/oeqa/runtime/cases/systemd.py > b/meta/lib/oeqa/runtime/cases/systemd.py > index 37f295492d..4c581ba396 100644 > --- a/meta/lib/oeqa/runtime/cases/systemd.py > +++ b/meta/lib/oeqa/runtime/cases/systemd.py > @@ -5,6 +5,7 @@ > # > > import re > +import threading > import time > > from oeqa.runtime.case import OERuntimeTestCase > @@ -136,6 +137,26 @@ class SystemdServiceTests(SystemdTest): > status = self.target.run('mount -oro,remount /')[0] > self.assertTrue(status == 0, msg='Remounting / as r/o failed') > > + @skipIfNotFeature('minidebuginfo', 'Test requires minidebuginfo to be > in DISTRO_FEATURES') > + @OEHasPackage(['busybox']) > + def test_systemd_coredump_minidebuginfo(self): > + """ > + Verify that call-stacks generated by systemd-coredump contain > symbolicated call-stacks, > + extracted from the minidebuginfo metadata (.gnu_debugdata elf > section). > + """ > + t_thread = threading.Thread(target=self.target.run, args=("ulimit > -c unlimited && sleep 1000",)) > + t_thread.start() > + time.sleep(1) > + > + status, output = self.target.run('pidof sleep') > + # cause segfault on purpose > + self.target.run('kill -SEGV %s' % output) > + self.assertEqual(status, 0, msg = 'Not able to find process that > runs sleep, output : %s' % output) > + > + (status, output) = self.target.run('coredumpctl info') > + self.assertEqual(status, 0, msg='MiniDebugInfo Test failed: %s' % > output) > + self.assertEqual('sleep_for_duration (busybox.nosuid' in output, > True, msg='Call stack is missing minidebuginfo symbols (functions shown as > "n/a"): %s' % output) > + > class SystemdJournalTests(SystemdTest): > > @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic']) > diff --git a/meta/lib/oeqa/selftest/cases/minidebuginfo.py > b/meta/lib/oeqa/selftest/cases/minidebuginfo.py > index aa1f9fa1f7..2919f07939 100644 > --- a/meta/lib/oeqa/selftest/cases/minidebuginfo.py > +++ b/meta/lib/oeqa/selftest/cases/minidebuginfo.py > @@ -21,7 +21,7 @@ class Minidebuginfo(OESelftestTestCase): > bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_LINK_NAME', > 'READELF'], image) > > self.write_config(""" > -PACKAGE_MINIDEBUGINFO = "1" > +DISTRO_FEATURES:append = " minidebuginfo" > IMAGE_FSTYPES = "tar.bz2" > """) > bitbake("{} {}:do_addto_recipe_sysroot".format(image, binutils)) > diff --git a/meta/recipes-core/systemd/systemd_254.4.bb > b/meta/recipes-core/systemd/systemd_254.4.bb > index 4d68a3266a..0c12926bef 100644 > --- a/meta/recipes-core/systemd/systemd_254.4.bb > +++ b/meta/recipes-core/systemd/systemd_254.4.bb > @@ -67,6 +67,7 @@ PAM_PLUGINS = " \ > > PACKAGECONFIG ??= " \ > ${@bb.utils.filter('DISTRO_FEATURES', 'acl audit efi ldconfig pam > selinux smack usrmerge polkit seccomp', d)} \ > + ${@bb.utils.contains('DISTRO_FEATURES', 'minidebuginfo', 'coredump > elfutils', '', d)} \ > ${@bb.utils.contains('DISTRO_FEATURES', 'wifi', 'rfkill', '', d)} \ > ${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'xkbcommon', '', d)} \ > ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', '', > 'link-udev-shared', d)} \ > diff --git a/meta/recipes-devtools/elfutils/elfutils_0.189.bb > b/meta/recipes-devtools/elfutils/elfutils_0.189.bb > index d8bf82b022..d69828131e 100644 > --- a/meta/recipes-devtools/elfutils/elfutils_0.189.bb > +++ b/meta/recipes-devtools/elfutils/elfutils_0.189.bb > @@ -39,7 +39,9 @@ BUILD_CFLAGS += "-Wno-error=stringop-overflow" > DEPENDS_BZIP2 = "bzip2-replacement-native" > DEPENDS_BZIP2:class-target = "bzip2" > > -PACKAGECONFIG ??= "${@bb.utils.contains('DISTRO_FEATURES', 'debuginfod', > 'debuginfod libdebuginfod', '', d)}" > +PACKAGECONFIG ??= "${@bb.utils.contains('DISTRO_FEATURES', 'debuginfod', > 'debuginfod libdebuginfod', '', d)} \ > + ${@bb.utils.contains('DISTRO_FEATURES', > 'minidebuginfo', 'xz', '', d)} \ > + " > PACKAGECONFIG[bzip2] = "--with-bzlib,--without-bzlib,${DEPENDS_BZIP2}" > PACKAGECONFIG[xz] = "--with-lzma,--without-lzma,xz" > PACKAGECONFIG[zstd] = "--with-zstd,--without-zstd,zstd" > diff --git a/meta/recipes-devtools/gdb/gdb-common.inc > b/meta/recipes-devtools/gdb/gdb-common.inc > index 3349719a6b..48dbb91463 100644 > --- a/meta/recipes-devtools/gdb/gdb-common.inc > +++ b/meta/recipes-devtools/gdb/gdb-common.inc > @@ -30,7 +30,9 @@ EXTRA_OECONF = "--disable-gdbtk --disable-x > --disable-werror \ > --with-libgmp-prefix=${STAGING_EXECPREFIXDIR} \ > " > > -PACKAGECONFIG ??= "readline ${@bb.utils.filter('DISTRO_FEATURES', > 'debuginfod', d)} python" > +PACKAGECONFIG ??= "readline ${@bb.utils.filter('DISTRO_FEATURES', > 'debuginfod', d)} python \ > + ${@bb.utils.contains('DISTRO_FEATURES', > 'minidebuginfo', 'xz', '', d)} \ > + " > # Use --without-system-readline to compile with readline 5. > PACKAGECONFIG[readline] = > "--with-system-readline,--without-system-readline,readline" > PACKAGECONFIG[python] = > "--with-python=${WORKDIR}/python,--without-python,python3,python3-codecs" > -- > 2.34.1 > >
On Tue, 2023-12-05 at 14:37 +0100, Etienne Cordonnier via lists.openembedded.org wrote: > From: Etienne Cordonnier <ecordonnier@snap.com> > > Enabling minidebuginfo is not useful if gdb and systemd-coredump > are unable to parse it. > > In order to parse it, gdb needs xz support. Systemd needs coredump enabled, as > well as elfutil enabled as well (systemd-coredump loads libdw which is part of elfutils using dlopen). > > Signed-off-by: Etienne Cordonnier <ecordonnier@snap.com> > --- > meta/classes-global/package.bbclass | 2 +- > meta/lib/oe/package.py | 2 +- > meta/lib/oeqa/runtime/cases/systemd.py | 21 +++++++++++++++++++ > meta/lib/oeqa/selftest/cases/minidebuginfo.py | 2 +- > meta/recipes-core/systemd/systemd_254.4.bb | 1 + > .../elfutils/elfutils_0.189.bb | 4 +++- > meta/recipes-devtools/gdb/gdb-common.inc | 4 +++- > 7 files changed, 31 insertions(+), 5 deletions(-) I merged this as I think it did improve things but adding a test change to poky to enable it hasn't quite worked as I hoped. I had to put a constraint around the test to ensure it only runs on systemd images: https://git.openembedded.org/openembedded-core/commit/?h=master-next&id=9c069e00a0867de11a6069b99a07d2c775848c10 and with that applied I then had this failure: https://autobuilder.yoctoproject.org/typhoon/#/builders/101/builds/7000/steps/14/logs/stdio I can queue the first patch but I'm not sure about the failure above. Any ideas? Cheers, Richard
diff --git a/meta/classes-global/package.bbclass b/meta/classes-global/package.bbclass index 2ad820a81f..f56bca3542 100644 --- a/meta/classes-global/package.bbclass +++ b/meta/classes-global/package.bbclass @@ -234,7 +234,7 @@ python () { deps = "" for dep in (d.getVar('PACKAGE_DEPENDS') or "").split(): deps += " %s:do_populate_sysroot" % dep - if d.getVar('PACKAGE_MINIDEBUGINFO') == '1': + if bb.utils.contains('DISTRO_FEATURES', 'minidebuginfo', True, False, d): deps += ' xz-native:do_populate_sysroot' d.appendVarFlag('do_package', 'depends', deps) diff --git a/meta/lib/oe/package.py b/meta/lib/oe/package.py index f69bf9c353..9a465eaa09 100644 --- a/meta/lib/oe/package.py +++ b/meta/lib/oe/package.py @@ -1239,7 +1239,7 @@ def process_split_and_strip_files(d): oe.utils.multiprocess_launch(oe.package.runstrip, sfiles, d) # Build "minidebuginfo" and reinject it back into the stripped binaries - if d.getVar('PACKAGE_MINIDEBUGINFO') == '1': + if bb.utils.contains('DISTRO_FEATURES', 'minidebuginfo', True, False, d): oe.utils.multiprocess_launch(inject_minidebuginfo, list(elffiles), d, extraargs=(dvar, dv, d)) diff --git a/meta/lib/oeqa/runtime/cases/systemd.py b/meta/lib/oeqa/runtime/cases/systemd.py index 37f295492d..4c581ba396 100644 --- a/meta/lib/oeqa/runtime/cases/systemd.py +++ b/meta/lib/oeqa/runtime/cases/systemd.py @@ -5,6 +5,7 @@ # import re +import threading import time from oeqa.runtime.case import OERuntimeTestCase @@ -136,6 +137,26 @@ class SystemdServiceTests(SystemdTest): status = self.target.run('mount -oro,remount /')[0] self.assertTrue(status == 0, msg='Remounting / as r/o failed') + @skipIfNotFeature('minidebuginfo', 'Test requires minidebuginfo to be in DISTRO_FEATURES') + @OEHasPackage(['busybox']) + def test_systemd_coredump_minidebuginfo(self): + """ + Verify that call-stacks generated by systemd-coredump contain symbolicated call-stacks, + extracted from the minidebuginfo metadata (.gnu_debugdata elf section). + """ + t_thread = threading.Thread(target=self.target.run, args=("ulimit -c unlimited && sleep 1000",)) + t_thread.start() + time.sleep(1) + + status, output = self.target.run('pidof sleep') + # cause segfault on purpose + self.target.run('kill -SEGV %s' % output) + self.assertEqual(status, 0, msg = 'Not able to find process that runs sleep, output : %s' % output) + + (status, output) = self.target.run('coredumpctl info') + self.assertEqual(status, 0, msg='MiniDebugInfo Test failed: %s' % output) + self.assertEqual('sleep_for_duration (busybox.nosuid' in output, True, msg='Call stack is missing minidebuginfo symbols (functions shown as "n/a"): %s' % output) + class SystemdJournalTests(SystemdTest): @OETestDepends(['systemd.SystemdBasicTests.test_systemd_basic']) diff --git a/meta/lib/oeqa/selftest/cases/minidebuginfo.py b/meta/lib/oeqa/selftest/cases/minidebuginfo.py index aa1f9fa1f7..2919f07939 100644 --- a/meta/lib/oeqa/selftest/cases/minidebuginfo.py +++ b/meta/lib/oeqa/selftest/cases/minidebuginfo.py @@ -21,7 +21,7 @@ class Minidebuginfo(OESelftestTestCase): bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'IMAGE_LINK_NAME', 'READELF'], image) self.write_config(""" -PACKAGE_MINIDEBUGINFO = "1" +DISTRO_FEATURES:append = " minidebuginfo" IMAGE_FSTYPES = "tar.bz2" """) bitbake("{} {}:do_addto_recipe_sysroot".format(image, binutils)) diff --git a/meta/recipes-core/systemd/systemd_254.4.bb b/meta/recipes-core/systemd/systemd_254.4.bb index 4d68a3266a..0c12926bef 100644 --- a/meta/recipes-core/systemd/systemd_254.4.bb +++ b/meta/recipes-core/systemd/systemd_254.4.bb @@ -67,6 +67,7 @@ PAM_PLUGINS = " \ PACKAGECONFIG ??= " \ ${@bb.utils.filter('DISTRO_FEATURES', 'acl audit efi ldconfig pam selinux smack usrmerge polkit seccomp', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'minidebuginfo', 'coredump elfutils', '', d)} \ ${@bb.utils.contains('DISTRO_FEATURES', 'wifi', 'rfkill', '', d)} \ ${@bb.utils.contains('DISTRO_FEATURES', 'x11', 'xkbcommon', '', d)} \ ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', '', 'link-udev-shared', d)} \ diff --git a/meta/recipes-devtools/elfutils/elfutils_0.189.bb b/meta/recipes-devtools/elfutils/elfutils_0.189.bb index d8bf82b022..d69828131e 100644 --- a/meta/recipes-devtools/elfutils/elfutils_0.189.bb +++ b/meta/recipes-devtools/elfutils/elfutils_0.189.bb @@ -39,7 +39,9 @@ BUILD_CFLAGS += "-Wno-error=stringop-overflow" DEPENDS_BZIP2 = "bzip2-replacement-native" DEPENDS_BZIP2:class-target = "bzip2" -PACKAGECONFIG ??= "${@bb.utils.contains('DISTRO_FEATURES', 'debuginfod', 'debuginfod libdebuginfod', '', d)}" +PACKAGECONFIG ??= "${@bb.utils.contains('DISTRO_FEATURES', 'debuginfod', 'debuginfod libdebuginfod', '', d)} \ + ${@bb.utils.contains('DISTRO_FEATURES', 'minidebuginfo', 'xz', '', d)} \ + " PACKAGECONFIG[bzip2] = "--with-bzlib,--without-bzlib,${DEPENDS_BZIP2}" PACKAGECONFIG[xz] = "--with-lzma,--without-lzma,xz" PACKAGECONFIG[zstd] = "--with-zstd,--without-zstd,zstd" diff --git a/meta/recipes-devtools/gdb/gdb-common.inc b/meta/recipes-devtools/gdb/gdb-common.inc index 3349719a6b..48dbb91463 100644 --- a/meta/recipes-devtools/gdb/gdb-common.inc +++ b/meta/recipes-devtools/gdb/gdb-common.inc @@ -30,7 +30,9 @@ EXTRA_OECONF = "--disable-gdbtk --disable-x --disable-werror \ --with-libgmp-prefix=${STAGING_EXECPREFIXDIR} \ " -PACKAGECONFIG ??= "readline ${@bb.utils.filter('DISTRO_FEATURES', 'debuginfod', d)} python" +PACKAGECONFIG ??= "readline ${@bb.utils.filter('DISTRO_FEATURES', 'debuginfod', d)} python \ + ${@bb.utils.contains('DISTRO_FEATURES', 'minidebuginfo', 'xz', '', d)} \ + " # Use --without-system-readline to compile with readline 5. PACKAGECONFIG[readline] = "--with-system-readline,--without-system-readline,readline" PACKAGECONFIG[python] = "--with-python=${WORKDIR}/python,--without-python,python3,python3-codecs"