[Crash-utility] [PATCH 2/2] symbols: fix the error belonging of the kernel modules symbols

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux