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
>
|