When a function is inlined (for example, as a result of it carrying the attribute alwaysinline), the cloned instructions receive the call site’s line number information (per r210459). After cloning, the cloned alloca instructions are moved to the caller’s entry block, retaining the call site’s line number information.
When, subsequently, new instructions are generated at the start of the caller’s entry block (such as instructions generated by the stack-protector pass), they pick up the line number information from the entry block’s first instruction, which may be one of the cloned alloca instructions.
This can cause incorrect line number information being generated for the start of the calling function, with an inlined function’s call site being associated with the first stack-protector instruction, for example. Since the stack-protector instruction is likely deemed to be the end of the function prologue, breakpoints that are set using the function name will be set at the wrong location.
Example:
int attribute((always_inline)) foo()
{
int arr[10]; arr[0] = 5; int sum = 4; return sum;
}
extern void bar();
int main()
{
bar(); int i = foo(); <== breaking at ‘main’ will stop here because main’s function prologue gets foo’s call site’s line number. return i;
}
The proposed fix is to modify the cloned alloca instructions’ debug information when they are moved to the caller’s entry block. Instead of the call site’s information they would get the same information as the instructions already at the start of the caller’s entry block, i.e. they place where they’re being moved to.
Note to the test case: the sspstrong attribute on the 'main' function is not necessary to make the test case pass, but if one were to generate a .o file the incorrect line numbers for the function prologue would not appear without the stack-protector instructions being generated.
Should we add nodebug to this function just to demonstrate why the other solutions we discussed were insufficient? (eg: we can't describe it as inlining, etc)
One day we might want to describe it as inlining in the non-nodebug case (and update the prologue handling code to cope with this), but we'd still need to do this for nodebug.
Or test both & describe that one /could/ change but mention the prologue complications.
Or just write a comment describing the gotchas here.