The address range may overlap for kernel modules global block vector, for example: module compunit_symtab block start block end floppy floppy.c ffffffffc0092000 ffffffffc00a4fa6 virtio_blk virtio_blk.c ffffffffc00a4000 ffffffffc00fd080 According to the gdb source code, the distance(block end - block start) of floppy(0x12fa6) is smaller than virtio_blk(0x59080), so address 0xffffffffc00a45b0, 0xffffffffc00a4370, 0xffffffffc00a4260 are translated by floppy module instead of virtio_blk module. However according to crash, the address range for the 2 modules are: crash> sym -l ffffffffc0092000 MODULE START: floppy ...snip... ffffffffc00a2f29 MODULE END: floppy ffffffffc00a4000 MODULE START: virtio_blk ...snip... ffffffffc00a86ec MODULE END: virtio_blk So the block vector address arrange and distance is not a reliable way to determine the symbol belonging of a specific kernel module. This patch will let gdb to query the module address range from crash, in order to locate the symbol belongings more percisely. Without the patch: crash> mod -S crash> struct blk_mq_ops 0xffffffffc00a7160 struct blk_mq_ops { queue_rq = 0xffffffffc00a45b0 <floppy_module_init+1151>, <-- symbol translated from module floppy map_queue = 0xffffffff813015c0 <blk_mq_map_queue>, ...snip... complete = 0xffffffffc00a4370 <floppy_module_init+575>, init_request = 0xffffffffc00a4260 <floppy_module_init+303>, ...snip... } With the patch: crash> mod -S crash> struct blk_mq_ops 0xffffffffc00a7160 struct blk_mq_ops { queue_rq = 0xffffffffc00a45b0 <virtio_queue_rq>, <-- symbol translated from module virtio_blk map_queue = 0xffffffff813015c0 <blk_mq_map_queue>, ...snip... complete = 0xffffffffc00a4370 <virtblk_request_done>, init_request = 0xffffffffc00a4260 <virtblk_init_request>, ...snip... } Signed-off-by: Tao Liu <ltao@xxxxxxxxxx> --- defs.h | 2 ++ gdb-10.2.patch | 37 ++++++++++++++++++++++++++++++++++++- gdb_interface.c | 18 ++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/defs.h b/defs.h index 788f63a..09e6738 100644 --- a/defs.h +++ b/defs.h @@ -5130,6 +5130,7 @@ struct syment *symbol_search(char *); int gdb_line_number_callback(ulong, ulong, ulong); int gdb_print_callback(ulong); char *gdb_lookup_module_symbol(ulong, ulong *); +ulong gdb_get_module_boundary(const char *, bool); extern "C" int same_file(char *, char *); #endif @@ -7687,6 +7688,7 @@ int gdb_readmem_callback(ulong, void *, int, int); int gdb_line_number_callback(ulong, ulong, ulong); int gdb_print_callback(ulong); char *gdb_lookup_module_symbol(ulong, ulong *); +ulong gdb_get_module_boundary(const char *, bool); void gdb_error_hook(void); void restore_gdb_sanity(void); int is_gdb_command(int, ulong); diff --git a/gdb-10.2.patch b/gdb-10.2.patch index 31135ca..a5c10d3 100644 --- a/gdb-10.2.patch +++ b/gdb-10.2.patch @@ -3203,4 +3203,39 @@ exit 0 +#endif for (compunit_symtab *cust : obj_file->compunits ()) { - const struct block *b; \ No newline at end of file + const struct block *b; +--- gdb-10.2/gdb/symtab.c.orig ++++ gdb-10.2/gdb/symtab.c +@@ -2895,6 +2895,10 @@ iterate_over_symbols_terminated + return callback (&block_sym); + } + ++#ifdef CRASH_MERGE ++extern "C" ulong gdb_get_module_boundary(const char *, bool); ++#endif ++ + /* Find the compunit symtab associated with PC and SECTION. + This will read in debug info as necessary. */ + +@@ -2932,11 +2936,21 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section) + for (objfile *obj_file : current_program_space->objfiles ()) + { + #ifdef CRASH_MERGE ++ size_t sep; + std::string objfile_name = objfile_filename(obj_file); ++ const char *mod_name; + + if (objfile_name.find(".ko") != std::string::npos) { + if (obj_file->sf && obj_file->compunit_symtabs == nullptr) + obj_file->sf->qf->expand_all_symtabs(obj_file); ++ sep = objfile_name.find_last_of("/"); ++ objfile_name = objfile_name.substr(sep + 1, objfile_name.size() - sep - 1); ++ sep = objfile_name.find_first_of("."); ++ objfile_name = objfile_name.substr(0, sep); ++ mod_name = objfile_name.c_str(); ++ if (pc < gdb_get_module_boundary(mod_name, true) || ++ pc > gdb_get_module_boundary(mod_name, false)) ++ continue; + } + #endif + for (compunit_symtab *cust : obj_file->compunits ()) diff --git a/gdb_interface.c b/gdb_interface.c index b14319c..a58fd68 100644 --- a/gdb_interface.c +++ b/gdb_interface.c @@ -947,6 +947,24 @@ gdb_lookup_module_symbol(ulong addr, ulong *offset) } } +ulong +gdb_get_module_boundary(const char *module, bool is_start) +{ + char buf[256]; + struct syment *sp; + + if (is_start) { + snprintf(buf, sizeof(buf), "_MODULE_START_%s", module); + } else { + snprintf(buf, sizeof(buf), "_MODULE_END_%s", module); + } + sp = symbol_search(buf); + if (sp) + return sp->value; + else + return is_start ? 0 : (ulong)(-1); +} + /* * Used by gdb_interface() to catch gdb-related errors, if desired. */ -- 2.40.1 -- Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s Contribution Guidelines: https://github.com/crash-utility/crash/wiki