[llvm-bugs] [Bug 38338] New: Debugger stops twice for delegating (complete -> base) constructors

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Jul 27 06:07:16 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=38338

            Bug ID: 38338
           Summary: Debugger stops twice for delegating (complete -> base)
                    constructors
           Product: clang
           Version: unspecified
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: LLVM Codegen
          Assignee: unassignedclangbugs at nondot.org
          Reporter: labath at google.com
                CC: aprantl at apple.com, brock.wyma at intel.com,
                    dblaikie at gmail.com, echristo at gmail.com,
                    jdevlieghere at apple.com, llvm-bugs at lists.llvm.org

Under some circumstances(*) clang will emit the complete (C1) constructor
variant as a delegate call to the base (C2) variant. In this case the C1
variant doesn't really do anything, and is probably uniteresting for most
people. However, from a debugger POV, these are separate functions, and both of
them have line numbers associated with them.

So if a user sets a breakpoint at the "right line" in the constructor, this
breakpoint will resolve to both functions, and will be hit twice (once for each
variant), even though there is only one object being constructed. This behavior
can be confusing/annoying to the user.

Fixing this from the debugger side is tricky, because the debugger doesn't know
that the C1 variant is just a shim around C2. Theoretically, we could
disassemble the C1 function and check for calls to C2, but things could quickly
get messy(**).

Therefore, I think it's best to fix this from the compiler side. I think the
best solution is to not emit line table entries for the C1 shim constructor (or
even better emit them as line 0, reserved for compiler-generated code). I think
this would make sense, as there really is no user code in that function. I've
tried implementing this idea, and it seemed achievable, though the patch ended
up being fairly messy, because I needed to duplicate the logic for detecting
when a constructor will delegate. I also don't know if there is anything else
which might be depending on the current behavior.



(*) I think this used to be limited to apple targets, which don't set the
-mconstructor-aliases cc1 option. However, after r337456 (which tries to solve
a different debug info problem), it started happening in other cases too. This
means another option would be to revert that commit, which would restore the
previous behavior for elf, but it wouldn't help the apple targets. It also
might be possible to rework that patch to emit C1->C2 aliases (instead of
shims) in more cases, but that also won't work on apple, as it cannot use
aliases for some reason.



(**) A convoluted example:

struct A { A(...); };

struct B: public A {
  B() __attribute__((always_inline)) : A() {}
};

bool rand();

inline A::A(...) { if(rand()) B(); }

A a;

Here the C1 variant for class A will contain a call to the C2 variant. However,
it would be wrong to skip setting a breakpoint in C1 because this is not a shim
constructor (we cannot emit delegating shims for varargs constructors).

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180727/854dba53/attachment.html>


More information about the llvm-bugs mailing list