<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
 
<br><tt>> There still are a couple of things which need to be done, viz</tt>
<br><tt>> 1. Extend to obtaining unwind info from modules as well(currently</tt>
<br><tt>>    doing only for the kernel)</tt>
<br><tt>> 2. Currently reading the unwind info from eh_frame section only(ie</tt>
<br><tt>>    __start_unwind to __end_unwind). Need to add
facility to read from</tt>
<br><tt>>    the .debug_frame(if .debug_frame is present
in cases where .eh_frame</tt>
<br><tt>>    is absent. Will have to read from the vmlinux
if we want to read the</tt>
<br><tt>>    .debug_frame info)</tt>
<p><tt>Hi Rachita,</tt><tt></tt>
<p><tt>I hope to be able to come up with a new crash version</tt>
<br><tt>for you to continue working with by tomorrow, Monday at</tt>
<br><tt>the latest.</tt><tt></tt>
<p><tt>Off the top of my head, here's what I've done with your</tt>
<br><tt>initial patch:</tt><tt></tt>
<p><tt>1. As Ben mentioned, it need to be made compilable for</tt>
<br><tt>   other architectures.</tt>
<br><tt>2. Renamed unwind_x86_64.c into unwind_x86_32_64.c,</tt>
<br><tt>   because the unwind code should be architecture</tt>
<br><tt>   neutral with respect to x86 and x86_64.  It's
currently</tt>
<br><tt>   #ifdef'd to only be compile if X86_64, but when a</tt>
<br><tt>   new "unwind_x86.h" file is ready to go, it can be</tt>
<br><tt>   made usable by both arches.</tt>
<br><tt>3. Made it capable of reading .eh_frame data from the</tt>
<br><tt>   vmlinux file if it is not in memory.</tt>
<br><tt>4. Made it capable of reading all of the module's unwind</tt>
<br><tt>   tables.</tt>
<br><tt>5. Restored the unwind() function to reflect the kernel</tt>
<br><tt>   version in that it new uses a new find_table() routine,</tt>
<br><tt>   which returns a pointer to the local copy of the unwind</tt>
<br><tt>   that contains the incoming pc.</tt>
<br><tt>6. Cleaned up a bunch of cruft...</tt><tt></tt>
<p><tt>A couple other notes:</tt><tt></tt>
<p><tt>I've restored the original x86_64_low_budget_back_trace_cmd()</tt>
<br><tt>function, and renamed your modified version of it.  I can't</tt>
<br><tt>risk breaking the original, and having a new version that</tt>
<br><tt>can be swapped in dynamically to the machdep->back_trace</tt>
<br><tt>pointer will allow us to tinker with the new one.  Ideally</tt>
<br><tt>the new one could continue to use the multiple stack walkers</tt>
<br><tt>of the original function, but as they walk through the stacks</tt>
<br><tt>from a "known good" starting point, they could use the new</tt>
<br><tt>unwind functionality to simply calculate the frame size,</tt>
<br><tt>and thereby skip over the leftovers -- as opposed to laboriously</tt>
<br><tt>printing every kernel text return address found -- and as</tt>
<br><tt>opposed to the way you send it off to dwarf_backtrace().</tt>
<br><tt>That being said, your dwarf_backtrace() function is an</tt>
<br><tt>excellent proof-of-concept!</tt><tt></tt>
<p><tt>The same thing goes for the x86 port.  In a perfect scenario,</tt>
<br><tt>the back trace code can be left pretty much untouched</tt>
<br><tt>*except* for one key function, that being the get_framesize()</tt>
<br><tt>function in lkcd_x86_trace.c.  As the backtrace code is</tt>
<br><tt>walking through the proces and IRQ stacks, it starts with</tt>
<br><tt>the "known good" PC, and calls get_framesize() to determine</tt>
<br><tt>how much of the stack to skip over to find the next text</tt>
<br><tt>return reference.  That code has been hacked to hell, and</tt>
<br><tt>as the compiler has gotten more and more clever, it's been</tt>
<br><tt>more and more prone to miscalculating the frame size.  It</tt>
<br><tt>disassembles the code from the start of the containing function</tt>
<br><tt>of the passed-in PC up to the PC, counts pushes and pops,</tt>
<br><tt>subtractions of the stack pointer, tries to handle embedded</tt>
<br><tt>returns, etc, etc. -- it's a nightmare.  But it seemingly</tt>
<br><tt>could take the passed in PC, and just pass it the unwind</tt>
<br><tt>code to get a "confident" frame size, and go from there.</tt><tt></tt>
<p><tt>That's what I'm hoping for, anyway...</tt><tt></tt>
<p><tt>Anyway, the use of the new unwind info is turned "off" by</tt>
<br><tt>default, but you can turn it on during runtime by entering</tt>
<br><tt>"set unwind on", or turn it off by entering "set unwind off".</tt>
<br><tt>Of course it will not allow you to turn it on if the kernel</tt>
<br><tt>and vmlinux both don't contain any unwind info.</tt><tt></tt>
<p><tt>BTW, I also tried using the .debug_frame section of the vmlinux</tt>
<br><tt>file, but it apparently can not be used by the ported</tt>
<br><tt>kernel unwind code.  The kernel unwind code presumes the</tt>
<br><tt>data is from the .eh_frame section; the .debug_frame section</tt>
<br><tt>must use a different layout.</tt><tt></tt>
<p><tt>This is looking good...</tt><tt></tt>
<p><tt>Thanks,</tt>
<br><tt>  Dave</tt><tt></tt>
<p><tt> </tt>
<br> </html>