[Crash-utility] Re: [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]

 



Hi Kazu,

On Tue, Nov 7, 2023 at 1:07 PM HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab@xxxxxxx> wrote:
>
> Hi Tao,
>
> thank you for the patches.
>
> On 2023/11/02 21:09, Tao Liu wrote:
> > 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
>
> hmm, this condition looks strange in the first place, is it inevitable?
> In other words, I wonder if there might be something wrong with how to
> load module symbol files.
>

Honestly I'm not sure why there is address overlap of the 2 modules
global block, it shouldn't happen from my view. But it can happen on
another kernel(4.18.0-425.13.1.el8_7.x86_64), see the results blow:

module            compunit_symtab     block start            block end
libata.ko.debug libata-core.c ffffffffc054f000 ffffffffc0591b18
mgag200.ko.debug mgag200_drv.c ffffffffc03f3000 ffffffffc0595b0e

module address boundary:
crash> sym -l
ffffffffc054f000 MODULE START: libata
...snip...
ffffffffc0590000 MODULE END: libata
ffffffffc0591000 MODULE START: mgag200
...snip...
ffffffffc059a000 MODULE END: mgag200

> What is the kernel version?

The kernel which I used to create the patch is 3.10.0-693.2.2.el7.x86_64.

> Do you have any patch to debug the gdb internal information?

Sure, simple debug patch as follows:
diff --git gdb-10.2/gdb/symtab.c.orig gdb-10.2/gdb/symtab.c
index 82605cc..3af3570 100644
--- gdb-10.2/gdb/symtab.c.orig
+++ gdb-10.2/gdb/symtab.c
@@ -2939,6 +2939,8 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc,
struct obj_section *section)
          bv = COMPUNIT_BLOCKVECTOR (cust);
          b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);

+          printf("%s %s %lx %lx\n", objfile_filename(obj_file),
cust->name, BLOCK_START (b), BLOCK_END (b));
+
          if (BLOCK_START (b) <= pc
              && BLOCK_END (b) > pc
              && (distance == 0
>
> I'd like to check vmcores on hand..

I can share the vmcore with you by a private email later.

Thanks,
Tao Liu

>
> Thanks,
> Kazu
>
> >
> > 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.
> >    */
--
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