debug line info of a landing pad

Hi,

As a basis of this discussion, I compile the following two C++ files and
then step through them with gdb 7.2.

$ clang++ -g test1.cc test2.cc -o a.out
$ gdb a.out

/* begin of test1.cc */
struct foo {
  foo();
  ~foo();
  int get() { return a; }

private:
  int a;
};

foo::foo() { a = 16; }
foo::~foo() { a = 0; }

extern "C" void call_me_yellow();
extern "C" void call_you_green();

int main()
{
  int c = 100;

  try {
    foo my_foo;
    call_me_yellow(); // landing pad #1

    foo your_foo;
    call_you_green(); // landing pad #2
  }

  catch (int a) {
    c = a;
  }

  return c;
}
/* end of test1.cc */

/* begin of test2.cc */
extern "C" void call_me_yellow()
{
  throw 1;
}

extern "C" void call_you_green()
{
  throw 2;
}
/* end of test2.cc */

Since call_me_yellow() could throw an exception, Clang generates a landing
pad for it. The debug line info of this landing pad is associated with the
function call. If I set a breakpoint on the landing pad in gdb, this source
line shows up when the breakpoint is hit.
22 call_me_yellow(); // landing pad #1

One customer asked, why does the debugger not stop at the beginning of the
catch block when the exception is thrown.

If I compile using GCC 4.4.3, the landing pads do not have associated debug
line info, and because they immediately follow the generated codes for the
try block, they implicitly get attached to the last statement in the try
block. If I set a breakpoint on the landing pad in gdb, this source line
shows up when the breakpoint is hit. Not really at the beginning of the catch
block, but closer.
25 call_you_green(); // landing pad #2

So my question is, should the landing pads have associated debug line info at
all, and what do you think are the reasonable source lines to attach them to?
Here are some of the options that I can think of:
    (a) no debug line info (like what gcc does)
    (b) the call site (like what clang does)
    (c) the beginning of the (lexicographically) first catch block if any;
    (d) the end of the innermost enclosing try block;

The same questions could be asked regarding the EHResume block as well.

As a side note, in gdb, I had to use "break *<address>" to put a breakpoint
on the landing pad; "break test1.cc:22" does not put a breakpoint on the
landing pad. This seems like a gdb bug, although, for this discussion, I'd
like to focus on the debug info generated by the compiler.

Thanks for your options,
- Gao.

From: cfe-dev-bounces@cs.uiuc.edu [mailto:cfe-dev-bounces@cs.uiuc.edu]
On Behalf Of Gao, Yunzhong

As a basis of this discussion, I compile the following two C++ files and
then step through them with gdb 7.2.

$ clang++ -g test1.cc test2.cc -o a.out
$ gdb a.out

/* begin of test1.cc */
struct foo {
  foo();
  ~foo();
  int get() { return a; }

private:
  int a;
};

foo::foo() { a = 16; }
foo::~foo() { a = 0; }

extern "C" void call_me_yellow();
extern "C" void call_you_green();

int main()
{
  int c = 100;

  try {
    foo my_foo;
    call_me_yellow(); // landing pad #1

    foo your_foo;
    call_you_green(); // landing pad #2
  }

  catch (int a) {
    c = a;
  }

  return c;
}
/* end of test1.cc */

/* begin of test2.cc */
extern "C" void call_me_yellow()
{
  throw 1;
}

extern "C" void call_you_green()
{
  throw 2;
}
/* end of test2.cc */

Since call_me_yellow() could throw an exception, Clang generates a
landing
pad for it. The debug line info of this landing pad is associated with
the
function call. If I set a breakpoint on the landing pad in gdb, this
source
line shows up when the breakpoint is hit.
22 call_me_yellow(); // landing pad #1

One customer asked, why does the debugger not stop at the beginning of
the
catch block when the exception is thrown.

If I compile using GCC 4.4.3, the landing pads do not have associated
debug
line info, and because they immediately follow the generated codes for
the
try block, they implicitly get attached to the last statement in the try
block. If I set a breakpoint on the landing pad in gdb, this source line
shows up when the breakpoint is hit. Not really at the beginning of the
catch
block, but closer.
25 call_you_green(); // landing pad #2

So my question is, should the landing pads have associated debug line
info at
all, and what do you think are the reasonable source lines to attach
them to?
Here are some of the options that I can think of:
    (a) no debug line info (like what gcc does)
    (b) the call site (like what clang does)
    (c) the beginning of the (lexicographically) first catch block if
any;
    (d) the end of the innermost enclosing try block;

The same questions could be asked regarding the EHResume block as well.

I discussed this with Gao but we'd like some feedback from outside.
Basically, (a) means that the landing pad block becomes associated with
the same source loc as the block that physically precedes it, which is
not entirely predictable. I can understand why (b) happens but I think
really (c) or maybe (d) would be preferable from a debugging-experience
perspective.

Also I think the more likely scenario is not so much trying to set a
breakpoint on the landing pad (which requires real effort on the part
of the user) but 'step' or 'finish' over a throw.

Eric/David, any thoughts here?
Thanks,
--paulr

+Eric, ping?

I don’t necessarily have any brilliant ideas here. I think, in general, that I’d expect them to have a line number of the closing brace as a “doing something not listed in the actual code” and in particular a column number of the closing brace in cases where we care about that.

-eric