]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CONTRIB: trace: try to display the function's return value on exit
authorWilly Tarreau <w@1wt.eu>
Tue, 24 Oct 2017 08:58:20 +0000 (10:58 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 24 Oct 2017 17:54:25 +0000 (19:54 +0200)
On x86_64, when gcc instruments functions and compiles at -O0, it saves
the function's return value in register rbx before calling the trace
callback. It provides a nice opportunity to display certain useful
values (flags, booleans etc) during trace sessions. It's absolutely
not guaranteed that it will always work but it provides a considerable
help when it does so it's worth activating it. When building on a
different architecture, the value 0 is always reported as the return
value. On x86_64 with optimizations (-O), the RBX register will not
necessarily match and random values will be reported, but since it's
not the primary target it's not a problem.

contrib/trace/trace.awk
src/trace.c

index 6bd5b10a5a3fe3b75bdcc4582103b60fb5bc88ec..74d953ccdcdbbcd385ac34afde4c01c8772d6c1d 100755 (executable)
@@ -72,7 +72,7 @@ function getptr(ptr)
   }
   getptr($3); caller_loc=loc; caller_name=name
   getptr($5); callee_loc=loc; callee_name=name
-  printf "%s %s  %s %s %s [%s:%s] %s [%s:%s]\n",
-    $1, indents[$4,$2], caller_name, $4, callee_name, caller_loc, $3, $4, callee_loc, $5
+  printf "%s %s  %s %s %s(%s) [%s:%s] %s [%s:%s]\n",
+    $1, indents[$4,$2], caller_name, $4, callee_name, $6, caller_loc, $3, $4, callee_loc, $5
 }
 '
index 9425be9f713de0a3c42bc596a6d39201b098ff8b..ab23a74eda492e23f82e04af11617e409113aed9 100644 (file)
@@ -171,7 +171,7 @@ static char *emit_hex(unsigned long h, char *out)
        return out;
 }
 
-static void make_line(void *from, void *to, int level, char dir)
+static void make_line(void *from, void *to, int level, char dir, long ret)
 {
        char *p = line;
 
@@ -221,6 +221,12 @@ static void make_line(void *from, void *to, int level, char dir)
        *p++ = ' '; *p++ = '0'; *p++ = 'x';
        p = emit_hex((unsigned long)to, p);
 
+       if (dir == '<') {
+               /* " %x", ret */
+               *p++ = ' '; *p++ = '0'; *p++ = 'x';
+               p = emit_hex(ret, p);
+       }
+
        *p++ = '\n';
 
        fwrite(line, p - line, 1, log);
@@ -230,13 +236,21 @@ static void make_line(void *from, void *to, int level, char dir)
 void __cyg_profile_func_enter(void *to,  void *from)
 {
        if (!disabled)
-               return make_line(from, to, ++level, '>');
+               return make_line(from, to, ++level, '>', 0);
 }
 
 void __cyg_profile_func_exit(void *to,  void *from)
 {
+       long ret = 0;
+
+#if defined(__x86_64__)
+       /* on x86_64, the return value (eax) is temporarily stored in ebx
+        * during the call to __cyg_profile_func_exit() so we can snoop it.
+        */
+       asm volatile("mov %%rbx, %0" : "=r"(ret));
+#endif
        if (!disabled)
-               return make_line(from, to, level--, '<');
+               return make_line(from, to, level--, '<', ret);
 }
 
 /* the one adds comments in the trace above. The output format is :