[PATCH 2/2] stack trace support: print full instruction pointer in addition to offset

Thomas De Schampheleire patrickdepinguin at gmail.com
Thu Nov 6 12:59:05 UTC 2014


From: Thomas De Schampheleire <thomas.de.schampheleire at gmail.com>

Currently, stack traces only show the offset of an instruction pointer
(from the start of the text mapping):

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
= 0x5e000
 > /lib/libc-2.10.1.so(_IO_file_doallocate+0x8c) [0x68a38]
 > /lib/libc-2.10.1.so(_IO_doallocbuf+0x6c) [0x78574]
 > /lib/libc-2.10.1.so(_IO_file_overflow+0x184) [0x7763c]
 > /lib/libc-2.10.1.so(_IO_file_xsputn+0x88) [0x76aac]
 > /lib/libc-2.10.1.so(_IO_puts+0xc8) [0x6b64c]
 > /bin/busybox() [0x62c60]
 > /bin/busybox() [0x4940]
 > /bin/busybox() [0x499c]
 > /bin/busybox() [0x4e08]
 > /lib/libc-2.10.1.so(__libc_init_first+0x30c) [0x1f84c]
 > /lib/libc-2.10.1.so(__libc_start_main+0xd8) [0x1f9f8]

This is in contrast with the type of output of tools like nm, that show
the full instruction pointer. In order to decode addresses of programs
that have no symbolic information on target, this full instruction
pointer is needed.

This patch prints out this full instruction pointer in addition to the
existing offset, for example:

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x5e000
 > /lib/libc-2.10.1.so(_IO_file_doallocate+0x8c) [0xfed8a38]/[0x68a38]
 > /lib/libc-2.10.1.so(_IO_doallocbuf+0x6c) [0xfee8574]/[0x78574]
 > /lib/libc-2.10.1.so(_IO_file_overflow+0x184) [0xfee763c]/[0x7763c]
 > /lib/libc-2.10.1.so(_IO_file_xsputn+0x88) [0xfee6aac]/[0x76aac]
 > /lib/libc-2.10.1.so(_IO_puts+0xc8) [0xfedb64c]/[0x6b64c]
 > /bin/busybox() [0x10062c60]/[0x62c60]
 > /bin/busybox() [0x10004940]/[0x4940]
 > /bin/busybox() [0x1000499c]/[0x499c]
 > /bin/busybox() [0x10004e08]/[0x4e08]
 > /lib/libc-2.10.1.so(__libc_init_first+0x30c) [0xfe8f84c]/[0x1f84c]
 > /lib/libc-2.10.1.so(__libc_start_main+0xd8) [0xfe8f9f8]/[0x1f9f8]

Signed-off-by: Thomas De Schampheleire <thomas.de.schampheleire at gmail.com>
---
 unwind.c |   18 +++++++++++++-----
 1 files changed, 13 insertions(+), 5 deletions(-)

Note: I would find it more logical to only show the full instruction pointer,
instead of both the instruction pointer and the offset. But I'm not sure if
everyone would agree to that.


diff --git a/unwind.c b/unwind.c
index 6f422a1..31974bc 100644
--- a/unwind.c
+++ b/unwind.c
@@ -66,6 +66,7 @@ struct mmap_cache_t {
 typedef void (*call_action_fn)(void *data,
 			       const char *binary_filename,
 			       const char *symbol_name,
+			       unsigned long ip,
 			       unw_word_t function_offset,
 			       unsigned long true_offset);
 typedef void (*error_action_fn)(void *data,
@@ -333,6 +334,7 @@ print_stack_frame(struct tcb *tcp,
 			call_action(data,
 				    cur_mmap_cache->binary_filename,
 				    *symbol_name,
+				    ip,
 				    function_offset,
 				    true_offset);
 			return 0;
@@ -405,14 +407,14 @@ stacktrace_walk(struct tcb *tcp,
  * ./a.out() [0x400569]
  */
 #define STACK_ENTRY_SYMBOL_FMT			\
-	" > %s(%s+0x%lx) [0x%lx]\n",		\
+	" > %s(%s+0x%lx) [0x%lx]/[0x%lx]\n",	\
 	binary_filename,			\
 	symbol_name,				\
 	(unsigned long) function_offset,	\
-	true_offset
+	ip, true_offset
 #define STACK_ENTRY_NOSYMBOL_FMT		\
-	" > %s() [0x%lx]\n",			\
-	binary_filename, true_offset
+	" > %s() [0x%lx]/[0x%lx]\n",		\
+	binary_filename, ip, true_offset
 #define STACK_ENTRY_BUG_FMT			\
 	" > BUG IN %s\n"
 #define STACK_ENTRY_ERROR_WITH_OFFSET_FMT	\
@@ -424,6 +426,7 @@ static void
 print_call_cb(void *dummy,
 	      const char *binary_filename,
 	      const char *symbol_name,
+	      unsigned long ip,
 	      unw_word_t function_offset,
 	      unsigned long true_offset)
 {
@@ -453,6 +456,7 @@ print_error_cb(void *dummy,
 static char *
 sprint_call_or_error(const char *binary_filename,
 		     const char *symbol_name,
+		     unsigned long ip,
 		     unw_word_t function_offset,
 		     unsigned long true_offset,
 		     const char *error)
@@ -484,6 +488,7 @@ static void
 queue_put(struct queue_t *queue,
 	  const char *binary_filename,
 	  const char *symbol_name,
+	  unsigned long ip,
 	  unw_word_t function_offset,
 	  unsigned long true_offset,
 	  const char *error)
@@ -496,6 +501,7 @@ queue_put(struct queue_t *queue,
 
 	call->output_line = sprint_call_or_error(binary_filename,
 						 symbol_name,
+						 ip,
 						 function_offset,
 						 true_offset,
 						 error);
@@ -514,12 +520,14 @@ static void
 queue_put_call(void *queue,
 	       const char *binary_filename,
 	       const char *symbol_name,
+	       unsigned long ip,
 	       unw_word_t function_offset,
 	       unsigned long true_offset)
 {
 	queue_put(queue,
 		  binary_filename,
 		  symbol_name,
+		  ip,
 		  function_offset,
 		  true_offset,
 		  NULL);
@@ -530,7 +538,7 @@ queue_put_error(void *queue,
 		const char *error,
 		unsigned long ip)
 {
-	queue_put(queue, NULL, NULL, 0, ip, error);
+	queue_put(queue, NULL, NULL, ip, 0, ip, error);
 }
 
 static void
-- 
1.7.1





More information about the Strace-devel mailing list