-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Incorrect line number in debuginfo when duplicate callsites are merged together at -O1 #65667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@llvm/issue-subscribers-debuginfo |
Thanks for pinning down the issue; unfortunately this is the correct debug-info behaviour for the given optimisation. Branch-folding is merging together two identical function tails (the LEA, call, and trap being identical and terminal) and there isn't a correct single source line that can be attributed to those instructions. If either path is picked (line 16 or 18) then when taking the other path through the program a false + misleading line number would be displayed in the stack trace. Line zero, signalling that the location is compiler generated and not a "real" source line, is the least worst output in this scenario. The main blocker on improving this is that there aren't many good ways of describing ambiguous source locations in DWARF, or conventions on how they should be interpreted by consumers, which is an ongoing pain point. |
Why is the line set to 0 but the column to 23 which doesn't match either call site? |
Most likely, if you look at the last |
Thanks @jmorse! I suspected that was the case when filing and couldn't think of a good resolution other than simply picking one of the lines. I'll note that gdb seems to pick a nearby, non-zero line from the line table where as lldb just reports zero. It might be reasonable to pick one of the lines rather than zero as users debugging optimized code are already used to the current line jumping around somewhat unexpectedly. That might be more intuitive for them than the current line simply disappearing entirely but the exact experience there is debugger specific. |
I filed an upstream issue related to this problem almost four years ago. The context for that is profiling rather than debugging, and I agree that picking one of the lines would be much better in that context. Even if the chosen line is slightly wrong it will still be in the same function. In contrast, zero only gives file-level data, which is much less useful when profiling. |
The complete lack of source information for line-zero is indeed a serious problem -- I think (98% confidence) that we include the instruction in the lexical scope that's most-common to the merged instructions, so technically a debugger would be able to present something, however I know very little about the consumer side of things. We've steered clear of presenting sometimes-false information to developers in the past (when the compiler makes decisions) as we feel that it'll undermine developers' confidence in the accuracy of debug-info, doing more harm than good. I'm going to close this as it's a known problem, but please do re-open if there's more to say. There's a sort-of vague plan of how we might address this in the future: we've got a prototype for the two-level-line-tables proposal that might be in DWARF6, that can express the ambiguous source-location problem, and there's the possibility that consumers could use the last-branch-record feature of modern processors to disambiguate merged source locations like these. It would require much more work, but in theory could address these issues. |
You could try |
Nothing helpful in this regard. (it adds things like discriminators to the line table and start lines to subprogram definitions even in Both for users and profiles we generally consider it worse/bad to pick one of the locations of instructions merged from basic blocks - for interactive users, they may be mislead into believing some code is reachable when it isn't, and for profile guided optimizations, similarly - it'd be bad if they were lead to believe that one branch was 100% hot and the other 100% cold, despite that not being true, just because they sampled a merged instruction. |
When the following IR is compiled with
llc -O1 -trap-unreachable
, an incorrect line number is generated in the debuginfo for the call topanic_test2::do_panic
:IR
godbolt
Notice that in the source IR, both calls to
do_panic
have the correct line numbers:However, when lowering to machine code, these line numbers are erased and replaced with line 0:
Looking at the optimization passes in godbolt, it seems that the "Control Flow Optimizer (branch-folder)" pass is responsible for merging the calls together and removing the correct line numbers.
The text was updated successfully, but these errors were encountered: