From cb619f41696f36a4a9df35912fb4205893a85d16 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sat, 9 Aug 2014 21:16:32 -0400 Subject: [PATCH] PR17249: tolerate early module notifier calls with null mod->sect_attrs In the case of MODULE_STATE_COMING, we may encounter NULL sect_attrs, and we must not crash. Sadly, that case can mean the loss of ability to probe module-init functions - i.e., breaking the bz6503 test case. * runtime/transport/symbols.c (_stp_module_notifier): Don't assume that mod->sect_attrs is valid. Treat COMING|LIVE notifications similarly, except LIVE should assume init.* gone gone gone, she been gone so long, she been gone gone gone so long. --- runtime/transport/symbols.c | 50 ++++++++++++++++------------- testsuite/systemtap.base/bz6503.exp | 5 +++ 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c index 60a4d596f..2a85823db 100644 --- a/runtime/transport/symbols.c +++ b/runtime/transport/symbols.c @@ -125,40 +125,44 @@ static int _stp_module_notifier (struct notifier_block * nb, /* Prior to 2.6.11, struct module contained a module_sections attribute vector rather than module_sect_attrs. Prior to 2.6.19, module_sect_attrs lacked a number-of-sections - field. Without CONFIG_KALLSYMS, we don't get any of the + field. Past 3.8, MODULE_STATE_COMING is sent too early to + let us probe module init functions. + + Without CONFIG_KALLSYMS, we don't get any of the related fields at all in struct module. XXX: autoconf for that directly? */ #if defined(CONFIG_KALLSYMS) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) struct module *mod = data; - struct module_sect_attrs *attrs = mod->sect_attrs; - unsigned i, nsections = _stp_module_nsections(attrs); - - if (val == MODULE_STATE_COMING) { - /* A module is arriving. Register all of its section - addresses, as though staprun sent us a bunch of - STP_RELOCATE messages. Now ... where did the - fishie go? */ - for (i=0; isect_attrs; + if (attrs == NULL) // until add_sect_attrs(), may be zero + return NOTIFY_DONE; // remain ignorant + + nsections = _stp_module_nsections(attrs); + for (i=0; iattrs[i].name, "init.") != NULL); + int init_gone_p = (val == MODULE_STATE_LIVE); // likely already unloaded + _stp_kmodule_update_address(mod->name, attrs->attrs[i].name, - attrs->attrs[i].address); + ((init_p && init_gone_p) ? 0 : attrs->attrs[i].address)); + } /* Verify build-id. */ if (_stp_kmodule_check (mod->name)) _stp_kmodule_update_address(mod->name, NULL, 0); /* Pretend it was never here. */ - } - else if (val == MODULE_STATE_LIVE) { - /* The init section(s) may have been unloaded. */ - for (i=0; iattrs[i].name, "init.") != NULL) - _stp_kmodule_update_address(mod->name, - attrs->attrs[i].name, - 0); - - /* No need to verify build-id here; if it failed when COMING, - all other section names will already have reloc=0. */ - } + } else if (val == MODULE_STATE_GOING) { /* Unregister all sections. */ _stp_kmodule_update_address(mod->name, NULL, 0); diff --git a/testsuite/systemtap.base/bz6503.exp b/testsuite/systemtap.base/bz6503.exp index 88fc26c1d..5d4d2d065 100644 --- a/testsuite/systemtap.base/bz6503.exp +++ b/testsuite/systemtap.base/bz6503.exp @@ -5,6 +5,11 @@ # Not BZ6503: # ypserve does not work # +# +# Unfortunately, PR17249 indicates that module-init probes +# have subsequently broken (due to kernel notification timing +# changes). +# set test bz6503 -- 2.43.5