> There still are a couple of things which need to be done, viz
> 1. Extend to obtaining unwind info from modules as well(currently
>    doing only for the kernel)
> 2. Currently reading the unwind info from eh_frame section only(ie
>    __start_unwind to __end_unwind). Need to add facility to read from
>    the .debug_frame(if .debug_frame is present in cases where .eh_frame
>    is absent. Will have to read from the vmlinux if we want to read the
>    .debug_frame info)

Hi Rachita,

I hope to be able to come up with a new crash version
for you to continue working with by tomorrow, Monday at
the latest.

Off the top of my head, here's what I've done with your
initial patch:

1. As Ben mentioned, it need to be made compilable for
   other architectures.
2. Renamed unwind_x86_64.c into unwind_x86_32_64.c,
   because the unwind code should be architecture
   neutral with respect to x86 and x86_64.  It's currently
   #ifdef'd to only be compile if X86_64, but when a
   new "unwind_x86.h" file is ready to go, it can be
   made usable by both arches.
3. Made it capable of reading .eh_frame data from the
   vmlinux file if it is not in memory.
4. Made it capable of reading all of the module's unwind
   tables.
5. Restored the unwind() function to reflect the kernel
   version in that it new uses a new find_table() routine,
   which returns a pointer to the local copy of the unwind
   that contains the incoming pc.
6. Cleaned up a bunch of cruft...

A couple other notes:

I've restored the original x86_64_low_budget_back_trace_cmd()
function, and renamed your modified version of it.  I can't
risk breaking the original, and having a new version that
can be swapped in dynamically to the machdep->back_trace
pointer will allow us to tinker with the new one.  Ideally
the new one could continue to use the multiple stack walkers
of the original function, but as they walk through the stacks
from a "known good" starting point, they could use the new
unwind functionality to simply calculate the frame size,
and thereby skip over the leftovers -- as opposed to laboriously
printing every kernel text return address found -- and as
opposed to the way you send it off to dwarf_backtrace().
That being said, your dwarf_backtrace() function is an
excellent proof-of-concept!

The same thing goes for the x86 port.  In a perfect scenario,
the back trace code can be left pretty much untouched
*except* for one key function, that being the get_framesize()
function in lkcd_x86_trace.c.  As the backtrace code is
walking through the proces and IRQ stacks, it starts with
the "known good" PC, and calls get_framesize() to determine
how much of the stack to skip over to find the next text
return reference.  That code has been hacked to hell, and
as the compiler has gotten more and more clever, it's been
more and more prone to miscalculating the frame size.  It
disassembles the code from the start of the containing function
of the passed-in PC up to the PC, counts pushes and pops,
subtractions of the stack pointer, tries to handle embedded
returns, etc, etc. -- it's a nightmare.  But it seemingly
could take the passed in PC, and just pass it the unwind
code to get a "confident" frame size, and go from there.

That's what I'm hoping for, anyway...

Anyway, the use of the new unwind info is turned "off" by
default, but you can turn it on during runtime by entering
"set unwind on", or turn it off by entering "set unwind off".
Of course it will not allow you to turn it on if the kernel
and vmlinux both don't contain any unwind info.

BTW, I also tried using the .debug_frame section of the vmlinux
file, but it apparently can not be used by the ported
kernel unwind code.  The kernel unwind code presumes the
data is from the .eh_frame section; the .debug_frame section
must use a different layout.

This is looking good...

Thanks,
  Dave