From 3bfa753fa12560af05b008a7070b75908e843665 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Tue, 6 Nov 2012 01:14:52 +0000 Subject: [PATCH] Add a workaround to problems with the clang debug info for inlined subroutine ranges. llvm-svn: 167430 --- .../xcshareddata/xcschemes/lldb-tool.xcscheme | 2 +- .../source/Target/ThreadPlanStepOverRange.cpp | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme index 101410da85a6..4caf434136ec 100644 --- a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme +++ b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme @@ -84,7 +84,7 @@ GetSymbolContext (eSymbolContextEverything); + if (sc.line_entry.IsValid()) + { + if (sc.line_entry.file != m_addr_context.line_entry.file + && sc.comp_unit == m_addr_context.comp_unit + && sc.function == m_addr_context.function) + { + // Okay, find the next occurance of this file in the line table: + LineTable *line_table = m_addr_context.comp_unit->GetLineTable(); + if (line_table) + { + Address cur_address = frame_sp->GetFrameCodeAddress(); + uint32_t entry_idx; + LineEntry line_entry; + if (line_table->FindLineEntryByAddress (cur_address, line_entry, &entry_idx)) + { + LineEntry next_line_entry; + bool step_past_remaining_inline = false; + if (entry_idx > 0) + { + // We require the the previous line entry and the current line entry come + // from the same file. + // The other requirement is that the previous line table entry be part of an + // inlined block, we don't want to step past cases where people have inlined + // some code fragment by using #include directly. + LineEntry prev_line_entry; + if (line_table->GetLineEntryAtIndex(entry_idx - 1, prev_line_entry) + && prev_line_entry.file == line_entry.file) + { + SymbolContext prev_sc; + Address prev_address = prev_line_entry.range.GetBaseAddress(); + prev_address.CalculateSymbolContext(&prev_sc); + if (prev_sc.block) + { + Block *inlined_block = prev_sc.block->GetContainingInlinedBlock(); + if (inlined_block) + { + AddressRange inline_range; + inlined_block->GetRangeContainingAddress(prev_address, inline_range); + if (!inline_range.ContainsFileAddress(cur_address)) + { + + step_past_remaining_inline = true; + } + + } + } + } + } + + if (step_past_remaining_inline) + { + uint32_t look_ahead_step = 1; + while (line_table->GetLineEntryAtIndex(entry_idx + look_ahead_step, next_line_entry)) + { + // Make sure we haven't wandered out of the function we started from... + Address next_line_address = next_line_entry.range.GetBaseAddress(); + Function *next_line_function = next_line_address.CalculateSymbolContextFunction(); + if (next_line_function != m_addr_context.function) + break; + + if (next_line_entry.file == m_addr_context.line_entry.file) + { + const bool abort_other_plans = false; + const bool stop_other_threads = false; + new_plan = m_thread.QueueThreadPlanForRunToAddress(abort_other_plans, + next_line_address, + stop_other_threads); + break; + } + look_ahead_step++; + } + } + } + } + } + } + } + } } // If we get to this point, we're not going to use a previously set "next branch" breakpoint, so delete it: