[llvm-dev] [RFC] Generate Debug Information for Labels in Function

Hsiangkai Wang via llvm-dev llvm-dev at lists.llvm.org
Tue Mar 27 19:41:20 PDT 2018


Hello all,

I would like to enhance LLVM debug info that supports setting
breakpoint on labels in function.

Generally, if users use GDB as their debugger, they could set
breakpoints on labels in function. Following is an example.

// C program
static int
myfunction (int arg)
{
  int i, j, r;

  j = 0; /* myfunction location */
  r = arg;

 top:
  ++j;  /* top location */

  if (j == 10)
    goto done;

  for (i = 0; i < 10; ++i)
    {
      r += i;
      if (j % 2)
        goto top;
    }

 done:
  return r;
}

int
main (void)
{
  int i, j;

  for (i = 0, j = 0; i < 1000; ++i)
    j += myfunction (0);

  return 0;
}

Following is the GDB commands to illustrate how to set breakpoints on labels.

(gdb) b main
Breakpoint 1 at 0x10298: file explicit.c, line 50.
(gdb) r
Starting program: /home/users/kai/sandbox/gdbtest/explicit-gcc

Breakpoint 1, main () at explicit.c:50
50  for (i = 0, j = 0; i < 1000; ++i)
(gdb) b myfunction:top
Breakpoint 2 at 0x10214: file explicit.c, line 26.
(gdb) c
Continuing.

Breakpoint 2, myfunction (arg=0) at explicit.c:27
27  ++j;  /\* top location */
(gdb)

However, LLVM does not generate debug information for labels. So, the
feature could not work for binaries generated by clang. I also found
that the problem is reported in PR35526 and PR36420. I propose an
implementation plan to support debug information for labels.

Following are the steps I propose to implement the feature.

1. Define debug metadata and intrinsic functions for labels.

First of all, we need to record debug information in LLVM IR. In LLVM
IR, LLVM uses metadata and intrinsic function to keep debug
information. So, I need to define new kind of metadata, DILabel, and
new intrinsic function, llvm.dbg.label, to associate DILabel with
label statement.

DILabel will contain name of the label, file metadata, line number,
and scope metadata.

Intrinsic function llvm.dbg.label uses DILabel metadata as its parameter.

2. Create MI instruction DBG_LABEL.

I create new MI instruction DBG_LABEL to keep debug information after
LLVM IR converted to MI.

DBG_LABEL uses DILabel metadata as its parameter.

3. Create data structure, SDDbgLabel, to store debug information of
labels in SelectionDAG.

In SelectionDAG, we need a data structure to keep debug information of
label. It will keep DILabel metadata.

4. Convert SDDbgLabel to DBG_LABEL in SelectionDAG.

After EmitSchedule(), SelectionDAG will be converted to a list of MI
instructions. In the function, we will generate DBG_LABEL MachineInstr
from SDDbgLabel.

For FastISel and GlobalISel, we could convert llvm.dbg.label to
DBG_LABEL directly.

5. Collect debug information of labels from MI listing to DebugHandlerBase.

Before generating actual debug information in assembly format or
object format, we need to keep debug format-independent data in
DebugHandlerBase. Afterwards, we could convert these data to CodeView
format or DWARF format.

6. Create DWARF DIE specific data structure in DwarfDebug.

In class DwarfDebug, we keep DWARF specific data structure for DILabel.

7. Generate DW_TAG_label and fill details of DW_TAG_label.

Finally, generating DW_TAG_label DIE and its attributes into DIE structure.

I am looking forward to any thoughts & feedback!


More information about the llvm-dev mailing list