For each stack frame prints the library path containing the code
pointed by the IP.
The output format is similar to the return value of backtrace_symbols
function found in glibc, e.g.:
 > /bin/ls(_init+0x19be) [0x40398e]
 > /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f50cbc3676d]
 > /bin/ls(_init+0x25fd) [0x4045cd]
---
 output.c |   38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/output.c b/output.c
index da8c419..d85c9b9 100644
--- a/output.c
+++ b/output.c
@@ -548,6 +548,7 @@ free_stringp_cb(const char **stringp, void *data)
        free((char *)*stringp);
 }
 
+
 void
 output_right(enum tof type, struct process *proc, struct library_symbol 
*libsym)
 {
@@ -670,16 +671,45 @@ again:
            && proc->unwind_priv != NULL
            && proc->unwind_as != NULL) {
                unw_cursor_t cursor;
-               unw_word_t ip, sp;
+               arch_addr_t ip;
+               unw_word_t function_offset, sp;
+               struct library *lib = NULL;
                int unwind_depth = options.bt_depth;
                char fn_name[100];
+               const char *lib_name;
+               size_t distance;
 
+               /* Verify that we can cast arch_addr_t to unw_word_t.  */
+               (void)sizeof(char[1 - 2*(sizeof(unw_word_t)
+                                       != sizeof(arch_addr_t))]);
                unw_init_remote(&cursor, proc->unwind_as, proc->unwind_priv);
                while (unwind_depth) {
-                       unw_get_reg(&cursor, UNW_REG_IP, &ip);
+                       unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip);
                        unw_get_reg(&cursor, UNW_REG_SP, &sp);
-                       unw_get_proc_name(&cursor, fn_name, 100, NULL);
-                       fprintf(options.output, "\t\t\t%s (ip = 0x%lx)\n", 
fn_name, (long) ip);
+                       unw_get_proc_name(&cursor, fn_name, sizeof(fn_name),
+                                       &function_offset);
+
+                       /* We are looking for the library with the base address
+                        * closest to the current ip.  */
+                       lib_name = "unmapped_area";
+                       distance = (size_t) -1;
+                       lib = proc->libraries;
+                       while (lib != NULL) {
+                               /* N.B.: Assumes sizeof(size_t) ==
+                                * sizeof(arch_addr_t).
+                                * Keyword: double cast.  */
+                               if ((ip >= lib->base) &&
+                                           ((size_t)(ip - lib->base)
+                                           < distance)) {
+                                       distance = ip - lib->base;
+                                       lib_name = lib->pathname;
+                               }
+                               lib = lib->next;
+                       }
+
+                       fprintf(options.output, " > %s(%s+0x%lx) [%p]\n",
+                                       lib_name, fn_name, function_offset, ip);
+
                        if (unw_step(&cursor) <= 0)
                                break;
                        unwind_depth--;
-- 
1.7.9.5


_______________________________________________
Ltrace-devel mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/ltrace-devel

Reply via email to