x86_64-m32 internal error for multi-thread-step.exp [Re: [PATCH v10 06/28] btrace: change branch trace data structure]

Message ID A78C989F6D9628469189715575E55B231E6C544C@IRSMSX104.ger.corp.intel.com
State New, archived

Commit Message

Markus Metzger Jan. 23, 2015, 12:53 p.m. UTC
  > -----Original Message-----
> From: Metzger, Markus T
> Sent: Friday, January 23, 2015 8:46 AM

> There also seem to be some issues in reverse/replay stepping.  The
> reverse-next command keeps going when it reached the previous
> source line; same for replay next.  I need to investigate why this is.

The 32-bit _dl_runtime_resolve returns to the resolved function.
The 64-bit _dl_runtime_resolve jumps to the resolved function.

The return causes btrace to search for the function in the current
stack back trace.  Since it doesn't find it, it assumes that the return
goes to some outer function that has not been recorded.

When we continue processing the trace, we build a new stack
back trace with the same function names but different frame id's.
They will look the same when using the bt command but stepping
won't be able to detect when stepping into a subroutine.

My current thinking is that I'd add a special case for this (see below).
I can't think of a general case where you would use a return instruction
to transfer control to a function that didn't call you.  If you know of
more such cases, please let me know.


Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052


diff --git a/gdb/btrace.c b/gdb/btrace.c
index fd543ef..db31788 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -524,7 +524,24 @@  ftrace_update_function (struct btrace_function *bfun, CORE_ADDR pc)
       switch (last->iclass)
        case BTRACE_INSN_RETURN:
-         return ftrace_new_return (bfun, mfun, fun);
+         {
+           const char *fname;
+           /* On some systems, _dl_runtime_resolve returns to the resolved
+              function instead of jumping to it.  From our perspective,
+              however, this is a tailcall.
+              If we treated it as return, we wouldn't be able to find the
+              resolved function in our stack back trace.  Hence, we would
+              lose the current stack back trace and start anew with an empty
+              back trace.  When the resolved function returns, we would then
+              create a stack back trace with the same function names but
+              different frame id's.  This will confuse stepping.  */
+           fname = ftrace_print_function_name (bfun);
+           if (strcmp (fname, "_dl_runtime_resolve") == 0)
+             return ftrace_new_tailcall (bfun, mfun, fun);
+           return ftrace_new_return (bfun, mfun, fun);
+         }
        case BTRACE_INSN_CALL:
          /* Ignore calls to the next instruction.  They are used for PIC.  */