mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 09:32:01 +00:00
Fix off-by-one inline function info in stack traces
This commit is contained in:
parent
008d02880b
commit
3ca00440af
@ -248,8 +248,31 @@ void StackTrace::forEachFrame(
|
||||
auto dwarf_it = dwarfs.try_emplace(object->name, object->elf).first;
|
||||
|
||||
DB::Dwarf::LocationInfo location;
|
||||
if (dwarf_it->second.findAddress(
|
||||
uintptr_t(current_frame.physical_addr), location, mode, inline_frames))
|
||||
uintptr_t adjusted_addr = uintptr_t(current_frame.physical_addr);
|
||||
if (i > 0)
|
||||
{
|
||||
/// For non-innermost stack frames, the address points to the *next* instruction
|
||||
/// after the `call` instruction. But we want the line number and inline function
|
||||
/// information for the `call` instruction. So subtract 1 from the address.
|
||||
/// Caveats:
|
||||
/// * The `call` instruction can be longer than 1 byte, so addr-1 is in the middle
|
||||
/// of the instruction. That's ok for debug info lookup: address ranges in debug
|
||||
/// info cover the whole instruction.
|
||||
/// * If the stack trace unwound out of a signal handler, the stack frame just
|
||||
/// outside the signal didn't do a function call. It was interrupted by signal.
|
||||
/// There's no `call` instruction, and decrementing the address is incorrect.
|
||||
/// We may get incorrect line number and inlined functions in this case.
|
||||
/// Unfortunate.
|
||||
/// Note that libunwind, when producing this stack trace, knows whether this
|
||||
/// frame is interrupted by signal or not. We could propagate this information
|
||||
/// from libunwind to here and avoid subtracting 1 in this case, but currently
|
||||
/// we don't do this.
|
||||
/// But we don't do the decrement for findSymbol() below (because `call` is
|
||||
/// ~never the last instruction of a function), so the function name should be
|
||||
/// correct for both pre-signal frames and regular frames.
|
||||
adjusted_addr -= 1;
|
||||
}
|
||||
if (dwarf_it->second.findAddress(adjusted_addr, location, mode, inline_frames))
|
||||
{
|
||||
current_frame.file = location.file.toString();
|
||||
current_frame.line = location.line;
|
||||
|
Loading…
Reference in New Issue
Block a user