lkcd
[Top] [All Lists]

Re: lkcd with modules

To: "Matt D. Robinson" <yakker@xxxxxxxxxxxxxx>
Subject: Re: lkcd with modules
From: Sushil <sushil@xxxxxxxxxxx>
Date: Wed, 20 Sep 2000 23:06:07 +0530 (IST)
Cc: lkcd@xxxxxxxxxxx, Sushil <sushil@xxxxxxxxxxx>
In-reply-to: <39C7AB29.47EF5699@xxxxxxxxxxxxxx>
Sender: owner-lkcd@xxxxxxxxxxx
Hi Matt,

    I added a small code to the kl_mem.c which converts a virtual address
to physical address through the page tables. The patch is appended below.

Using this code I am able to disassemble functions of a module which
resides in the saved dump. But when I try to print trace of processes
which were working with the module functions (using trace -a), lcrash
loops and infinitely oscillates between the kl_virtop() and
kl_virtop_nonident() (new function added) functions with the same set of
virtual addresses.

I am looking at it but surely suggestions/comments from you will help
in quickly locating and solving the problem.

Thanks and Regards.
Sushil. 


--- linux1/cmd/lcrash/lib/libklib/arch/i386/kl_mem.c    Wed Sep 20 13:38:28 2000
+++ linux/cmd/lcrash/lib/libklib/arch/i386/kl_mem.c     Wed Sep 20 13:23:17 2000
@@ -86,6 +86,45 @@
        return(paddr);
 }
 
+
+/*
+ * kl_virtop_nonident()
+ *
+ *   Translate a virtual address into a physical address without
+ *   assuming the identity mapping - works through page tables. 
+ *
+ */
+#define PGDIR_BASE 0x00101000
+#define PTRS_PER_PTE 1024
+kaddr_t
+kl_virtop_nonident(kaddr_t vaddr)
+{
+       kaddr_t dir_base, dir_off, dir_entry;
+       kaddr_t pte_base, pte, pte_val, paddr;
+
+       dir_base = PGDIR_BASE;
+       dir_off = (vaddr >> 22) * 4;
+       dir_entry = dir_base + dir_off;
+       kl_readmem(dir_entry, 4, &pte_base);
+       if (KL_ERROR) {
+               return(0);
+       }
+        /* Take the top 20 bits of the pgd entry */
+        pte_base &= 0xfffff000;
+        pte = pte_base + (((vaddr >> 12) & (PTRS_PER_PTE -1)) * 4);
+       kl_readmem(pte, 4, &pte_val);
+       if (KL_ERROR) {
+               return(0);
+       }
+        /* Take the top 20 bits of the pte entry */
+        paddr = pte_val & 0xfffff000; 
+
+        /* Go to the desired offset in the page */
+        paddr += (vaddr & (4096 -1));
+        return paddr;
+}
+
+
 /*
  * kl_virtop()
  *
@@ -105,7 +144,15 @@
                paddr = (KL_LOCORE_ADDR - KL_PAGE_OFFSET) + 
                                (vaddr - KL_LOCORE_START);
        } else if (vaddr >= KL_PAGE_OFFSET) {
+               static dump_header_t dh, *dhp = NULL;
                paddr = (vaddr - KL_PAGE_OFFSET);
+                if(!dhp) {
+                       get_dump_header(&dh);
+                        dhp = &dh;
+                }
+                if(paddr > dh.dh_memory_size * KL_PAGE_SIZE) {
+                        paddr = kl_virtop_nonident(vaddr);
+                }
        } else {
                if (!mmp && deftask) {
                        tsp = (struct task_struct*)

--- linux1/cmd/lcrash/lib/libklib/arch/i386/kl_task.c   Wed Sep 20 13:38:28 2000
+++ linux/cmd/lcrash/lib/libklib/arch/i386/kl_task.c    Wed Sep 20 13:25:18 2000
@@ -153,7 +153,7 @@
 /*
  * get_dump_header()
  */
-static int
+int
 get_dump_header(dump_header_t *dump_header)
 {
        /* first, make sure this isn't a live system


---------------------------------------------------------------------------







On Tue, 19 Sep 2000, Matt D. Robinson wrote:

> Sushil wrote:
> > Hi,
> > 
> >      I am using lkcd with 2.4.0-test7 kernel using the latest lkcd
> > patch for 2.4.0-test7.
> > 
> >      Is it possible to use lkcd for debugging modules? Specifically,
> > is it possible to -
> > 
> > 1. get trace of a process which was executing a function from
> >         a dynamically loaded module at the time of crash?
> 
> Currently there's no mechanism for dumping out stack traces into
> modules.  This is something that still has to be done.  We realize
> it is a big hole in lcrash at this point, but other priorities,
> such as working with IA64, have taken precedence.
> 
> > 2. get the disassembly of a function from a dynamically loaded
> >         module whose pages are in the lkcd dump?
> 
> Same issue.  Disassembly works if it knows where to read the
> instructions from.
> 
> > assuming that the virtual addresses of module symbols are available
> > (using insmod -m) and are integrated with System.map and are
> > supplied to lcrash.
> > 
> > Using lcrash I am not able to do the above two things and
> > to me it seems impossible because lcrash converts
> > the virtual addresses to physical addresses by subtracting
> > the PAGE_OFFSET (= 0xc0000000) from the virtual address
> > 
> > (kl_virtop function in lib/libklib/arch/i386/kl_mem.c).
> > 
> > kl_virtop(kaddr_t vaddr, void *m)
> > {
> > 
> >         . . .
> > 
> >         } else if (vaddr >= KL_PAGE_OFFSET) {
> >                 paddr = (vaddr - KL_PAGE_OFFSET);
> > 
> >         . . .
> > 
> > }
> > 
> > This works fine with statically compiled kernel symbols but
> > does not work with modules because module symbols are assigned
> > virtual addresses much above the (PAGE_OFFSET + total_ram)
> > mark (using __vmalloc) and therefore virtual_address - PAGE_OFFSET
> > will not give the correct physical addresses for the virtual
> > addresses corresponding to module symbols.
> 
> Right.
> 
> > For example:
> >     In my case a module was assigned virtual addresses starting
> > from 0xc8829060. I have 128 MB of ram.
> > But (0xc8829060 - 0xc0000000) gives a starting physical address
> > of 142774368 for the module which is around 136 MB which is greater
> > than the total ram (128 MB). When lcrash tries to read this address
> > in the saved crash dump or in the online /dev/mem, it gets error because
> > that offset does not exist in the ram.
> > 
> > Is there a way to use lkcd with modules?
> 
> Again, not currently.  It's something that we know we have to do,
> but we're trying to finalize how to get our stuff into the kernel
> (the right way this time) and then we can attack that problem.
> Keith Owens has already spoken to us about helping to get this
> to work (even if it is just a pointer to some code he's written).
> 
> --Matt
> 




<Prev in Thread] Current Thread [Next in Thread>