[Lldb-commits] [lldb] r166757 - in /lldb/trunk: include/lldb/Symbol/ source/Plugins/ABI/MacOSX-arm/ source/Plugins/ABI/MacOSX-i386/ source/Plugins/ABI/SysV-x86_64/ source/Plugins/Instruction/ARM/ source/Plugins/Process/Utility/ source/Plugins/UnwindAssembly/x86/ source/Symbol/
Jason Molenda
jmolenda at apple.com
Thu Oct 25 23:08:59 PDT 2012
Author: jmolenda
Date: Fri Oct 26 01:08:58 2012
New Revision: 166757
URL: http://llvm.org/viewvc/llvm-project?rev=166757&view=rev
Log:
Add a new capability to RegisterContextLLDB: To recognize when the
Full UnwindPlan is trying to do an impossible unwind; in that case
invalidate the Full UnwindPlan and replace it with the architecture
default unwind plan.
This is a scenario that happens occasionally with arm unwinds in
particular; the instruction analysis based full unwindplan can
mis-parse the functions and the stack walk stops prematurely. Now
we can do a simpleminded frame-chain walk to find the caller frame
and continue the unwind. It's not ideal but given the complicated
nature of analyzing the arm functions, and the lack of eh_frame
information on iOS, it is a distinct improvement and fixes some
long-standing problems with the unwinder on that platform.
This is fixing <rdar://problem/12091421>. I may re-use this
invalidate feature in the future if I can identify other cases where
the full unwindplan's unwind information is clearly incorrect.
This checkin also includes some cleanup for the volatile register
definition in the arm ABI plugin for <rdar://problem/10652166>
although work remains to be done for that bug.
Modified:
lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
lldb/trunk/include/lldb/Symbol/UnwindPlan.h
lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h
lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
lldb/trunk/source/Symbol/FuncUnwinders.cpp
lldb/trunk/source/Symbol/UnwindPlan.cpp
Modified: lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/FuncUnwinders.h?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/FuncUnwinders.h (original)
+++ lldb/trunk/include/lldb/Symbol/FuncUnwinders.h Fri Oct 26 01:08:58 2012
@@ -70,6 +70,13 @@
return m_range.ContainsFileAddress (addr);
}
+ // When we're doing an unwind using the UnwindPlanAtNonCallSite and we find an
+ // impossible unwind condition, we know that the UnwindPlan is invalid. Calling
+ // this method on the FuncUnwinder will tell it to replace that UnwindPlan with
+ // the architectural default UnwindPlan so hopefully our stack walk will get past
+ // this frame.
+ void
+ InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& Thread);
private:
UnwindTable& m_unwind_table;
Modified: lldb/trunk/include/lldb/Symbol/UnwindPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/UnwindPlan.h?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/UnwindPlan.h (original)
+++ lldb/trunk/include/lldb/Symbol/UnwindPlan.h Fri Oct 26 01:08:58 2012
@@ -349,7 +349,9 @@
m_plan_valid_address_range (),
m_register_kind (reg_kind),
m_return_addr_register (LLDB_INVALID_REGNUM),
- m_source_name ()
+ m_source_name (),
+ m_plan_is_sourced_from_compiler (eLazyBoolCalculate),
+ m_plan_is_valid_at_all_instruction_locations (eLazyBoolCalculate)
{
}
@@ -432,6 +434,36 @@
void
SetSourceName (const char *);
+ // Was this UnwindPlan emitted by a compiler?
+ lldb_private::LazyBool
+ GetSourcedFromCompiler () const
+ {
+ return m_plan_is_sourced_from_compiler;
+ }
+
+ // Was this UnwindPlan emitted by a compiler?
+ void
+ SetSourcedFromCompiler (lldb_private::LazyBool from_compiler)
+ {
+ m_plan_is_sourced_from_compiler = from_compiler;
+ }
+
+ // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites,
+ // e.g. for exception handling.
+ lldb_private::LazyBool
+ GetUnwindPlanValidAtAllInstructions () const
+ {
+ return m_plan_is_valid_at_all_instruction_locations;
+ }
+
+ // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites,
+ // e.g. for exception handling.
+ void
+ SetUnwindPlanValidAtAllInstructions (lldb_private::LazyBool valid_at_all_insn)
+ {
+ m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn;
+ }
+
int
GetRowCount () const;
@@ -458,6 +490,8 @@
uint32_t m_return_addr_register; // The register that has the return address for the caller frame
// e.g. the lr on arm
lldb_private::ConstString m_source_name; // for logging, where this UnwindPlan originated from
+ lldb_private::LazyBool m_plan_is_sourced_from_compiler;
+ lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations;
}; // class UnwindPlan
} // namespace lldb_private
Modified: lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Fri Oct 26 01:08:58 2012
@@ -628,6 +628,8 @@
// All other registers are the same.
unwind_plan.SetSourceName ("arm at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+
return true;
}
@@ -651,9 +653,30 @@
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("arm-apple-ios default unwind plan");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
+
return true;
}
+// ARMv7 on iOS general purpose reg rules:
+// r0-r3 not preserved (used for argument passing)
+// r4-r6 preserved
+// r7 preserved (frame pointer)
+// r8 preserved
+// r9 not preserved (usable as volatile scratch register with iOS 3.x and later)
+// r10-r11 preserved
+// r12 not presrved
+// r13 preserved (stack pointer)
+// r14 not preserved (link register)
+// r15 preserved (pc)
+// cpsr not preserved (different rules for different bits)
+
+// ARMv7 on iOS floating point rules:
+// d0-d7 not preserved (aka s0-s15, q0-q3)
+// d8-d15 preserved (aka s16-s31, q4-q7)
+// d16-d31 not preserved (aka q8-q15)
+
bool
ABIMacOSX_arm::RegisterIsVolatile (const RegisterInfo *reg_info)
{
@@ -691,28 +714,28 @@
switch (name[1])
{
case '0':
- return name[2] == '\0'; // d0
+ return name[2] == '\0'; // d0 is volatile
case '1':
switch (name[2])
{
case '\0':
- return true; // d1;
+ return true; // d1 is volatile
case '6':
case '7':
case '8':
case '9':
- return name[3] == '\0'; // d16 - d19
+ return name[3] == '\0'; // d16 - d19 are volatile
default:
break;
}
break;
-
+
case '2':
switch (name[2])
{
case '\0':
- return true; // d2;
+ return true; // d2 is volatile
case '0':
case '1':
case '2':
@@ -723,7 +746,7 @@
case '7':
case '8':
case '9':
- return name[3] == '\0'; // d20 - d29
+ return name[3] == '\0'; // d20 - d29 are volatile
default:
break;
}
@@ -733,10 +756,62 @@
switch (name[2])
{
case '\0':
- return true; // d3;
+ return true; // d3 is volatile
+ case '0':
+ case '1':
+ return name[3] == '\0'; // d30 - d31 are volatile
+ default:
+ break;
+ }
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ return name[2] == '\0'; // d4 - d7 are volatile
+
+ default:
+ break;
+ }
+ }
+ else if (name[0] == 's')
+ {
+ switch (name[1])
+ {
+ case '0':
+ return name[2] == '\0'; // s0 is volatile
+
+ case '1':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // s1 is volatile
case '0':
case '1':
- return name[3] == '\0'; // d30 - d31
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ return name[3] == '\0'; // s10 - s15 are volatile
+ default:
+ break;
+ }
+ break;
+
+ case '2':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // s2 is volatile
+ default:
+ break;
+ }
+ break;
+
+ case '3':
+ switch (name[2])
+ {
+ case '\0':
+ return true; // s3 is volatile
default:
break;
}
@@ -744,7 +819,9 @@
case '5':
case '6':
case '7':
- return name[2] == '\0'; // d4 - d7
+ case '8':
+ case '9':
+ return name[2] == '\0'; // s4 - s9 are volatile
default:
break;
Modified: lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp Fri Oct 26 01:08:58 2012
@@ -894,6 +894,7 @@
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("i386 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
return true;
}
@@ -919,6 +920,8 @@
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("i386 default unwind plan");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
return true;
}
Modified: lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Fri Oct 26 01:08:58 2012
@@ -1088,6 +1088,7 @@
row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("x86_64 at-func-entry default");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
return true;
}
@@ -1139,6 +1140,8 @@
unwind_plan.AppendRow (row);
unwind_plan.SetSourceName ("x86_64 default unwind plan");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
return true;
}
Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Fri Oct 26 01:08:58 2012
@@ -13613,9 +13613,7 @@
// All other registers are the same.
unwind_plan.SetSourceName ("EmulateInstructionARM");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
return true;
}
-
-
-
-
Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Fri Oct 26 01:08:58 2012
@@ -35,24 +35,24 @@
using namespace lldb;
using namespace lldb_private;
-RegisterContextLLDB::RegisterContextLLDB
+RegisterContextLLDB::RegisterContextLLDB
(
- Thread& thread,
+ Thread& thread,
const SharedPtr &next_frame,
SymbolContext& sym_ctx,
uint32_t frame_number,
UnwindLLDB& unwind_lldb
) :
- RegisterContext (thread, frame_number),
- m_thread(thread),
+ RegisterContext (thread, frame_number),
+ m_thread(thread),
m_fast_unwind_plan_sp (),
m_full_unwind_plan_sp (),
m_all_registers_available(false),
m_frame_type (-1),
m_cfa (LLDB_INVALID_ADDRESS),
- m_start_pc (),
- m_current_pc (),
- m_current_offset (0),
+ m_start_pc (),
+ m_current_pc (),
+ m_current_offset (0),
m_current_offset_backed_up_one (0),
m_sym_ctx(sym_ctx),
m_sym_ctx_valid (false),
@@ -73,8 +73,8 @@
}
// This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet
- if (IsFrameZero()
- || next_frame->m_frame_type == eSigtrampFrame
+ if (IsFrameZero()
+ || next_frame->m_frame_type == eSigtrampFrame
|| next_frame->m_frame_type == eDebuggerFrame)
{
m_all_registers_available = true;
@@ -90,8 +90,6 @@
ExecutionContext exe_ctx(m_thread.shared_from_this());
RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
if (reg_ctx_sp.get() == NULL)
{
m_frame_type = eNotAValidFrame;
@@ -124,11 +122,7 @@
ModuleSP pc_module_sp (m_current_pc.GetModule());
if (!m_current_pc.IsValid() || !pc_module_sp)
{
- if (log)
- {
- log->Printf("%*sFrame %u using architectural default unwind method",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
- }
+ UnwindLogMsg ("using architectural default unwind method");
}
// We require that eSymbolContextSymbol be successfully filled in or this context is of no use to us.
@@ -140,7 +134,7 @@
AddressRange addr_range;
m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range);
-
+
static ConstString g_sigtramp_name ("_sigtramp");
if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == g_sigtramp_name) ||
(m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == g_sigtramp_name))
@@ -182,8 +176,8 @@
// We've set m_frame_type and m_sym_ctx before these calls.
m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
- m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
-
+ m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
+
UnwindPlan::RowSP active_row;
int cfa_offset = 0;
int row_register_kind = -1;
@@ -195,8 +189,7 @@
{
StreamString active_row_strm;
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- log->Printf("%*sFrame %u active row: %s",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
+ UnwindLogMsg ("%s", active_row_strm.GetString().c_str());
}
}
@@ -206,7 +199,7 @@
return;
}
-
+
addr_t cfa_regval;
if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval))
{
@@ -220,23 +213,11 @@
m_cfa = cfa_regval + cfa_offset;
- if (log)
- {
- log->Printf("%*sFrame %u cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- m_cfa, cfa_regval, cfa_offset);
- }
-
- if (log)
- {
- log->Printf("%*sThread %d Frame %u initialized frame current pc is 0x%llx cfa is 0x%llx using %s UnwindPlan",
- m_frame_number < 100 ? m_frame_number : 100, "",
- m_thread.GetIndexID(),
- m_frame_number,
- (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()),
- (uint64_t) m_cfa,
- m_full_unwind_plan_sp->GetSourceName().GetCString());
- }
+ UnwindLogMsg ("cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)", m_cfa, cfa_regval, cfa_offset);
+ UnwindLogMsg ("initialized frame current pc is 0x%llx cfa is 0x%llx using %s UnwindPlan",
+ (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()),
+ (uint64_t) m_cfa,
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
}
// Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the RegisterContextLLDB "below" it
@@ -246,13 +227,12 @@
RegisterContextLLDB::InitializeNonZerothFrame()
{
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
if (IsFrameZero ())
{
m_frame_type = eNotAValidFrame;
return;
}
-
+
if (!GetNextFrame().get() || !GetNextFrame()->IsValid())
{
m_frame_type = eNotAValidFrame;
@@ -267,27 +247,19 @@
addr_t pc;
if (!ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc))
{
- if (log)
- {
- log->Printf("%*sFrame %u could not get pc value",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
- }
+ UnwindLogMsg ("could not get pc value");
m_frame_type = eNotAValidFrame;
return;
}
-
+
if (log)
{
- log->Printf("%*sFrame %u pc = 0x%16.16llx",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, pc);
+ UnwindLogMsg ("pc = 0x%16.16llx", pc);
addr_t reg_val;
if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
- log->Printf("%*sFrame %u fp = 0x%16.16llx",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, reg_val);
-
+ UnwindLogMsg ("fp = 0x%16.16llx", reg_val);
if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
- log->Printf("%*sFrame %u sp = 0x%16.16llx",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, reg_val);
+ UnwindLogMsg ("sp = 0x%16.16llx", reg_val);
}
// A pc of 0x0 means it's the end of the stack crawl
@@ -296,11 +268,11 @@
m_frame_type = eNotAValidFrame;
return;
}
-
+
ExecutionContext exe_ctx(m_thread.shared_from_this());
Process *process = exe_ctx.GetProcessPtr();
// Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
- // this will strip bit zero in case we read a PC from memory or from the LR.
+ // this will strip bit zero in case we read a PC from memory or from the LR.
ABI *abi = process->GetABI().get();
if (abi)
pc = abi->FixCodeAddress(pc);
@@ -312,12 +284,8 @@
ModuleSP pc_module_sp (m_current_pc.GetModule());
if (!m_current_pc.IsValid() || !pc_module_sp)
{
- if (log)
- {
- log->Printf("%*sFrame %u using architectural default unwind method",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
- }
-
+ UnwindLogMsg ("using architectural default unwind method");
+
// Test the pc value to see if we know it's in an unmapped/non-executable region of memory.
uint32_t permissions;
if (process->GetLoadAddressPermissions(pc, permissions)
@@ -329,11 +297,8 @@
// pc and see if we can get any further.
if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsFrameZero())
{
- if (log)
- {
- log->Printf("%*sFrame %u had a pc of 0x%llx which is not in executable memory but on frame 1 -- allowing it once.",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, (uint64_t) pc);
- }
+ UnwindLogMsg ("had a pc of 0x%llx which is not in executable memory but on frame 1 -- allowing it once.",
+ (uint64_t) pc);
m_frame_type = eSkipFrame;
}
else
@@ -365,11 +330,7 @@
int cfa_offset = row->GetCFAOffset();
if (!ReadGPRValue (row_register_kind, cfa_regnum, cfa_regval))
{
- if (log)
- {
- log->Printf("%*sFrame %u failed to get cfa value",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
- }
+ UnwindLogMsg ("failed to get cfa value");
if (m_frame_type != eSkipFrame) // don't override eSkipFrame
{
m_frame_type = eNormalFrame;
@@ -381,11 +342,7 @@
// A couple of sanity checks..
if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1)
{
- if (log)
- {
- log->Printf("%*sFrame %u could not find a valid cfa address",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
- }
+ UnwindLogMsg ("could not find a valid cfa address");
m_frame_type = eNotAValidFrame;
return;
}
@@ -401,21 +358,12 @@
}
else
{
- if (log)
- {
- log->Printf("%*sFrame %u could not find a row for function offset zero",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
- }
+ UnwindLogMsg ("could not find a row for function offset zero");
m_frame_type = eNotAValidFrame;
return;
}
- if (log)
- {
- log->Printf("%*sFrame %u initialized frame cfa is 0x%llx",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- (uint64_t) m_cfa);
- }
+ UnwindLogMsg ("initialized frame cfa is 0x%llx", (uint64_t) m_cfa);
return;
}
m_frame_type = eNotAValidFrame;
@@ -456,7 +404,7 @@
// value is pointing to the next function, e.g. if a function ends with a CALL instruction.
// FIXME this may need to be an architectural-dependent behavior; if so we'll need to add a member function
// to the ABI plugin and consult that.
- if (decr_pc_and_recompute_addr_range)
+ if (decr_pc_and_recompute_addr_range)
{
Address temporary_pc(m_current_pc);
temporary_pc.SetOffset(m_current_pc.GetOffset() - 1);
@@ -522,11 +470,10 @@
{
StreamString active_row_strm;
active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- log->Printf("%*sFrame %u active row: %s",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
+ UnwindLogMsg ("active row: %s", active_row_strm.GetString().c_str());
}
}
- else
+ else
{
m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc))
@@ -537,8 +484,7 @@
{
StreamString active_row_strm;
active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
- log->Printf("%*sFrame %u active row: %s",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str());
+ UnwindLogMsg ("active row: %s", active_row_strm.GetString().c_str());
}
}
}
@@ -552,12 +498,7 @@
addr_t cfa_regval;
if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval))
{
- if (log)
- {
- log->Printf("%*sFrame %u failed to get cfa reg %d/%d",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- row_register_kind, active_row->GetCFARegister());
- }
+ UnwindLogMsg ("failed to get cfa reg %d/%d", row_register_kind, active_row->GetCFARegister());
m_frame_type = eNotAValidFrame;
return;
}
@@ -565,21 +506,12 @@
m_cfa = cfa_regval + cfa_offset;
- if (log)
- {
- log->Printf("%*sFrame %u cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- m_cfa, cfa_regval, cfa_offset);
- }
+ UnwindLogMsg ("cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)", m_cfa, cfa_regval, cfa_offset);
// A couple of sanity checks..
if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1)
- {
- if (log)
- {
- log->Printf("%*sFrame %u could not find a valid cfa address",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
- }
+ {
+ UnwindLogMsg ("could not find a valid cfa address");
m_frame_type = eNotAValidFrame;
return;
}
@@ -606,22 +538,14 @@
}
if (repeating_frames && abi->FunctionCallsChangeCFA())
{
- if (log)
- {
- log->Printf("%*sFrame %u same CFA address as next frame, assuming the unwind is looping - stopping",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number);
- }
+ UnwindLogMsg ("same CFA address as next frame, assuming the unwind is looping - stopping");
m_frame_type = eNotAValidFrame;
return;
}
}
- if (log)
- {
- log->Printf("%*sFrame %u initialized frame current pc is 0x%llx cfa is 0x%llx",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa);
- }
+ UnwindLogMsg ("initialized frame current pc is 0x%llx cfa is 0x%llx",
+ (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa);
}
@@ -634,9 +558,9 @@
// Find a fast unwind plan for this frame, if possible.
//
-// On entry to this method,
+// On entry to this method,
//
-// 1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct,
+// 1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct,
// 2. m_sym_ctx should already be filled in, and
// 3. m_current_pc should have the current pc value for this frame
// 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown
@@ -657,7 +581,7 @@
if (!func_unwinders_sp)
return unwind_plan_sp;
- // If we're in _sigtramp(), unwinding past this frame requires special knowledge.
+ // If we're in _sigtramp(), unwinding past this frame requires special knowledge.
if (m_frame_type == eSigtrampFrame || m_frame_type == eDebuggerFrame)
return unwind_plan_sp;
@@ -669,16 +593,15 @@
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (log && log->GetVerbose())
{
- const char *has_fast = "";
if (m_fast_unwind_plan_sp)
- has_fast = ", and has a fast UnwindPlan";
- log->Printf("%*sFrame %u frame%s",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, has_fast);
+ UnwindLogMsgVerbose ("frame, and has a fast UnwindPlan");
+ else
+ UnwindLogMsgVerbose ("frame");
}
m_frame_type = eNormalFrame;
return unwind_plan_sp;
}
- else
+ else
{
unwind_plan_sp.reset();
}
@@ -686,9 +609,9 @@
return unwind_plan_sp;
}
-// On entry to this method,
+// On entry to this method,
//
-// 1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct,
+// 1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct,
// 2. m_sym_ctx should already be filled in, and
// 3. m_current_pc should have the current pc value for this frame
// 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown
@@ -697,7 +620,6 @@
RegisterContextLLDB::GetFullUnwindPlanForFrame ()
{
UnwindPlanSP unwind_plan_sp;
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
UnwindPlanSP arch_default_unwind_plan_sp;
ExecutionContext exe_ctx(m_thread.shared_from_this());
Process *process = exe_ctx.GetProcessPtr();
@@ -709,12 +631,12 @@
}
bool behaves_like_zeroth_frame = false;
- if (IsFrameZero ()
+ if (IsFrameZero ()
|| GetNextFrame()->m_frame_type == eSigtrampFrame
|| GetNextFrame()->m_frame_type == eDebuggerFrame)
{
behaves_like_zeroth_frame = true;
- // If this frame behaves like a 0th frame (currently executing or
+ // If this frame behaves like a 0th frame (currently executing or
// interrupted asynchronously), all registers can be retrieved.
m_all_registers_available = true;
}
@@ -723,7 +645,7 @@
// in the zeroth frame, we need to use the "unwind at first instruction" arch default UnwindPlan
// Also, if this Process can report on memory region attributes, any non-executable region means
// we jumped through a bad function pointer - handle the same way as 0x0.
- // Note, if the symbol context has a function for the symbol, then we don't need to do this check.
+ // Note, if the symbol context has a function for the symbol, then we don't need to do this check.
if ((!m_sym_ctx_valid || m_sym_ctx.function == NULL) && behaves_like_zeroth_frame && m_current_pc.IsValid())
{
@@ -784,12 +706,8 @@
unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
{
- if (log && log->GetVerbose())
- {
- log->Printf("%*sFrame %u frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- unwind_plan_sp->GetSourceName().GetCString());
- }
+ UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it",
+ unwind_plan_sp->GetSourceName().GetCString());
return unwind_plan_sp;
}
}
@@ -800,12 +718,7 @@
unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (m_thread);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
{
- if (log && log->GetVerbose())
- {
- log->Printf("%*sFrame %u frame uses %s for full UnwindPlan",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- unwind_plan_sp->GetSourceName().GetCString());
- }
+ UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
return unwind_plan_sp;
}
}
@@ -814,36 +727,21 @@
unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
{
- if (log && log->GetVerbose())
- {
- log->Printf("%*sFrame %u frame uses %s for full UnwindPlan",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- unwind_plan_sp->GetSourceName().GetCString());
- }
+ UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
return unwind_plan_sp;
}
-
+
// We'd prefer to use an UnwindPlan intended for call sites when we're at a call site but if we've
// struck out on that, fall back to using the non-call-site assembly inspection UnwindPlan if possible.
unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (m_thread);
if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
{
- if (log && log->GetVerbose())
- {
- log->Printf("%*sFrame %u frame uses %s for full UnwindPlan",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- unwind_plan_sp->GetSourceName().GetCString());
- }
+ UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
return unwind_plan_sp;
}
// If nothing else, use the architectural default UnwindPlan and hope that does the job.
- if (log && log->GetVerbose())
- {
- log->Printf("%*sFrame %u frame uses %s for full UnwindPlan",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- arch_default_unwind_plan_sp->GetSourceName().GetCString());
- }
+ UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", arch_default_unwind_plan_sp->GetSourceName().GetCString());
return arch_default_unwind_plan_sp;
}
@@ -885,7 +783,7 @@
}
bool
-RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
+RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
const RegisterInfo *reg_info,
RegisterValue &value)
{
@@ -898,11 +796,11 @@
case UnwindLLDB::RegisterLocation::eRegisterInRegister:
{
const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
-
+
if (!other_reg_info)
return false;
-
- if (IsFrameZero ())
+
+ if (IsFrameZero ())
{
success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value);
}
@@ -915,7 +813,7 @@
case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
success = value.SetUInt (regloc.location.inferred_value, reg_info->byte_size);
break;
-
+
case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
break;
case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
@@ -923,9 +821,9 @@
break;
case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
{
- Error error (ReadRegisterValueFromMemory(reg_info,
- regloc.location.target_memory_location,
- reg_info->byte_size,
+ Error error (ReadRegisterValueFromMemory(reg_info,
+ regloc.location.target_memory_location,
+ reg_info->byte_size,
value));
success = error.Success();
}
@@ -938,7 +836,7 @@
}
bool
-RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
+RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
const RegisterInfo *reg_info,
const RegisterValue &value)
{
@@ -946,13 +844,13 @@
return false;
bool success = false;
-
+
switch (regloc.type)
{
case UnwindLLDB::RegisterLocation::eRegisterInRegister:
{
const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
- if (IsFrameZero ())
+ if (IsFrameZero ())
{
success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value);
}
@@ -970,9 +868,9 @@
break;
case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
{
- Error error (WriteRegisterValueToMemory (reg_info,
- regloc.location.target_memory_location,
- reg_info->byte_size,
+ Error error (WriteRegisterValueToMemory (reg_info,
+ regloc.location.target_memory_location,
+ reg_info->byte_size,
value));
success = error.Success();
}
@@ -994,7 +892,7 @@
// A skip frame is a bogus frame on the stack -- but one where we're likely to find a real frame farther
// up the stack if we keep looking. It's always the second frame in an unwind (i.e. the first frame after
// frame zero) where unwinding can be the trickiest. Ideally we'll mark up this frame in some way so the
-// user knows we're displaying bad data and we may have skipped one frame of their real program in the
+// user knows we're displaying bad data and we may have skipped one frame of their real program in the
// process of getting back on track.
bool
@@ -1006,10 +904,8 @@
// Answer the question: Where did THIS frame save the CALLER frame ("previous" frame)'s register value?
bool
-RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, bool check_next_frame)
+RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc)
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
-
// Have we already found this register location?
if (!m_registers.empty())
{
@@ -1022,11 +918,19 @@
}
}
+ static uint32_t sp_regnum = LLDB_INVALID_REGNUM;
+ static uint32_t pc_regnum = LLDB_INVALID_REGNUM;
+ static bool generic_registers_initialized = false;
+ if (!generic_registers_initialized)
+ {
+ m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, eRegisterKindLLDB, sp_regnum);
+ m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, eRegisterKindLLDB, pc_regnum);
+ generic_registers_initialized = true;
+ }
+
// Are we looking for the CALLER's stack pointer? The stack pointer is defined to be the same as THIS frame's
// CFA so just return the CFA value. This is true on x86-32/x86-64 at least.
- uint32_t sp_regnum;
- if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, eRegisterKindLLDB, sp_regnum)
- && sp_regnum == lldb_regnum)
+ if (sp_regnum != LLDB_INVALID_REGNUM && sp_regnum == lldb_regnum)
{
// make sure we won't lose precision copying an addr_t (m_cfa) into a uint64_t (.inferred_value)
assert (sizeof (addr_t) <= sizeof (uint64_t));
@@ -1036,12 +940,6 @@
return true;
}
- uint32_t pc_regnum;
- if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, eRegisterKindLLDB, pc_regnum))
- {
- pc_regnum = LLDB_INVALID_REGNUM;
- }
-
// Look through the available UnwindPlans for the register location.
UnwindPlan::Row::RegisterLocation unwindplan_regloc;
@@ -1055,22 +953,13 @@
uint32_t row_regnum;
if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
{
- if (log)
- {
- log->Printf("%*sFrame %u could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum, (int) unwindplan_registerkind);
- }
+ UnwindLogMsg ("could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
+ lldb_regnum, (int) unwindplan_registerkind);
return false;
}
if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))
{
- if (log)
- {
- log->Printf("%*sFrame %u supplying caller's saved reg %d's location using FastUnwindPlan",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsg ("supplying caller's saved reg %d's location using FastUnwindPlan", lldb_regnum);
have_unwindplan_regloc = true;
}
}
@@ -1092,27 +981,18 @@
if (lldb_regnum == pc_regnum && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM)
{
row_regnum = m_full_unwind_plan_sp->GetReturnAddressRegister();
- if (log)
- {
- log->Printf("%*sFrame %u requested caller's saved PC but this UnwindPlan uses a RA reg; getting reg %d instead",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, row_regnum);
- }
+ UnwindLogMsg ("requested caller's saved PC but this UnwindPlan uses a RA reg; getting reg %d instead",
+ row_regnum);
}
else
{
if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
{
- if (log)
- {
- if (unwindplan_registerkind == eRegisterKindGeneric)
- log->Printf("%*sFrame %u could not convert lldb regnum %d into eRegisterKindGeneric reg numbering scheme",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- else
- log->Printf("%*sFrame %u could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum, (int) unwindplan_registerkind);
- }
+ if (unwindplan_registerkind == eRegisterKindGeneric)
+ UnwindLogMsg ("could not convert lldb regnum %d into eRegisterKindGeneric reg numbering scheme", lldb_regnum);
+ else
+ UnwindLogMsg ("could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
+ lldb_regnum, (int) unwindplan_registerkind);
return false;
}
}
@@ -1120,22 +1000,62 @@
if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))
{
have_unwindplan_regloc = true;
- if (log)
- {
- log->Printf("%*sFrame %u supplying caller's saved reg %d's location using %s UnwindPlan",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum, m_full_unwind_plan_sp->GetSourceName().GetCString());
+ UnwindLogMsg ("supplying caller's saved reg %d's location using %s UnwindPlan", lldb_regnum,
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
+ }
+
+ // If this architecture stores the return address in a register (it defines a Return Address register)
+ // and we're on a non-zero stack frame and the Full UnwindPlan says that the pc is stored in the
+ // RA registers (e.g. lr on arm), then we know that the full unwindplan is not trustworthy -- this
+ // is an impossible situation and the instruction emulation code has likely been misled.
+ // If this stack frame meets those criteria, we need to throw away the Full UnwindPlan that the
+ // instruction emulation came up with and fall back to the architecture's Default UnwindPlan so
+ // the stack walk can get past this point.
+
+ // Special note: If the Full UnwindPlan was generated from the compiler, don't second-guess it
+ // when we're at a call site location.
+
+ // arch_default_ra_regnum is the return address register # in the Full UnwindPlan register numbering
+ uint32_t arch_default_ra_regnum = LLDB_INVALID_REGNUM;
+ if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, unwindplan_registerkind, arch_default_ra_regnum)
+ && arch_default_ra_regnum != LLDB_INVALID_REGNUM
+ && pc_regnum != LLDB_INVALID_REGNUM
+ && pc_regnum == lldb_regnum
+ && unwindplan_regloc.IsInOtherRegister()
+ && unwindplan_regloc.GetRegisterNumber() == arch_default_ra_regnum
+ && m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes
+ && !m_all_registers_available)
+ {
+ UnwindLogMsg ("%s UnwindPlan tried to restore the pc from the link register but this is a non-zero frame",
+ m_full_unwind_plan_sp->GetSourceName().GetCString());
+
+ // Throw away the full unwindplan; install the arch default unwindplan
+ InvalidateFullUnwindPlan();
+
+ // Now re-fetch the pc value we're searching for
+ uint32_t arch_default_pc_reg = LLDB_INVALID_REGNUM;
+ UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
+ if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, m_full_unwind_plan_sp->GetRegisterKind(), arch_default_pc_reg)
+ && arch_default_pc_reg != LLDB_INVALID_REGNUM
+ && active_row
+ && active_row->GetRegisterInfo (arch_default_pc_reg, unwindplan_regloc))
+ {
+ have_unwindplan_regloc = true;
+ }
+ else
+ {
+ have_unwindplan_regloc = false;
}
}
}
}
-
-
+
+
ExecutionContext exe_ctx(m_thread.shared_from_this());
Process *process = exe_ctx.GetProcessPtr();
if (have_unwindplan_regloc == false)
{
- // If a volatile register is being requested, we don't want to forward the next frame's register contents
+ // If a volatile register is being requested, we don't want to forward the next frame's register contents
// up the stack -- the register is not retrievable at this frame.
ABI *abi = process ? process->GetABI().get() : NULL;
if (abi)
@@ -1143,14 +1063,9 @@
const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
if (reg_info && abi->RegisterIsVolatile (reg_info))
{
- if (log && log->GetVerbose ())
- {
- log->Printf("%*sFrame %u did not supply reg location for %d because it is volatile",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsg ("did not supply reg location for %d because it is volatile", lldb_regnum);
return false;
- }
+ }
}
if (IsFrameZero ())
@@ -1164,16 +1079,7 @@
return true;
}
else
- {
- if (check_next_frame)
- return m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1);
- }
- if (log)
- {
- log->Printf("%*sFrame %u could not supply caller's reg %d location",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
return false;
}
@@ -1183,12 +1089,7 @@
lldb_private::UnwindLLDB::RegisterLocation new_regloc;
new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
m_registers[lldb_regnum] = new_regloc;
- if (log)
- {
- log->Printf("%*sFrame %u could not supply caller's reg %d location",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
return false;
}
@@ -1196,20 +1097,12 @@
{
if (IsFrameZero ())
{
- if (log)
- {
- log->Printf("%*sFrame %u could not supply caller's reg %d location",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
return false;
}
else
{
- if (check_next_frame)
- return m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1);
- else
- return false;
+ return false;
}
}
@@ -1237,12 +1130,7 @@
uint32_t row_regnum_in_lldb;
if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (unwindplan_registerkind, unwindplan_regnum, eRegisterKindLLDB, row_regnum_in_lldb))
{
- if (log)
- {
- log->Printf("%*sFrame %u could not supply caller's reg %d location",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
return false;
}
regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
@@ -1253,8 +1141,8 @@
if (unwindplan_regloc.IsDWARFExpression() || unwindplan_regloc.IsAtDWARFExpression())
{
- DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(),
- unwindplan_regloc.GetDWARFExpressionLength(),
+ DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(),
+ unwindplan_regloc.GetDWARFExpressionLength(),
process->GetByteOrder(), process->GetAddressByteSize());
DWARFExpression dwarfexpr (dwarfdata, 0, unwindplan_regloc.GetDWARFExpressionLength());
dwarfexpr.SetRegisterKind (unwindplan_registerkind);
@@ -1279,28 +1167,69 @@
return true;
}
}
- if (log)
- {
- log->Printf("%*sFrame %u tried to use IsDWARFExpression or IsAtDWARFExpression for reg %d but failed",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsg ("tried to use IsDWARFExpression or IsAtDWARFExpression for reg %d but failed", lldb_regnum);
return false;
}
- if (log)
- {
- log->Printf("%*sFrame %u could not supply caller's reg %d location",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
+
+ // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported.
-
- // assert ("UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported.");
return false;
}
-// Retrieve a general purpose register value for THIS from, as saved by the NEXT frame, i.e. the frame that
+// If the Full unwindplan has been determined to be incorrect, this method will
+// replace it with the architecture's default unwindplna, if one is defined.
+// It will also find the FuncUnwinders object for this function and replace the
+// Full unwind method for the function there so we don't use the errant Full unwindplan
+// again in the future of this debug session.
+// We're most likely doing this because the Full unwindplan was generated by assembly
+// instruction profiling and the profiler got something wrong.
+
+void
+RegisterContextLLDB::InvalidateFullUnwindPlan ()
+{
+ UnwindPlan::Row::RegisterLocation unwindplan_regloc;
+ ExecutionContext exe_ctx (m_thread.shared_from_this());
+ Process *process = exe_ctx.GetProcessPtr();
+ ABI *abi = process ? process->GetABI().get() : NULL;
+ if (abi)
+ {
+ UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
+ UnwindPlanSP arch_default_unwind_plan_sp;
+ arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
+ abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp);
+ if (arch_default_unwind_plan_sp)
+ {
+ UnwindPlan::RowSP active_row = arch_default_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
+
+ if (active_row && active_row->GetCFARegister() != LLDB_INVALID_REGNUM)
+ {
+ FuncUnwindersSP func_unwinders_sp;
+ if (m_sym_ctx_valid && m_current_pc.IsValid() && m_current_pc.GetModule())
+ {
+ func_unwinders_sp = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
+ if (func_unwinders_sp)
+ {
+ func_unwinders_sp->InvalidateNonCallSiteUnwindPlan (m_thread);
+ }
+ }
+ m_registers.clear();
+ m_full_unwind_plan_sp = arch_default_unwind_plan_sp;
+ addr_t cfa_regval;
+ if (ReadGPRValue (arch_default_unwind_plan_sp->GetRegisterKind(), active_row->GetCFARegister(), cfa_regval))
+ {
+ m_cfa = cfa_regval + active_row->GetCFAOffset ();
+ }
+
+ UnwindLogMsg ("full unwind plan '%s' has been replaced by architecture default unwind plan '%s' for this function from now on.",
+ original_full_unwind_plan_sp->GetSourceName().GetCString(), arch_default_unwind_plan_sp->GetSourceName().GetCString());
+ }
+ }
+ }
+}
+
+// Retrieve a general purpose register value for THIS frame, as saved by the NEXT frame, i.e. the frame that
// this frame called. e.g.
//
// foo () { }
@@ -1343,8 +1272,21 @@
return false;
}
+ bool pc_or_return_address = false;
+ uint32_t generic_regnum;
+ if (register_kind == eRegisterKindGeneric
+ && (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA))
+ {
+ pc_or_return_address = true;
+ }
+ else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindGeneric, generic_regnum)
+ && (generic_regnum == LLDB_REGNUM_GENERIC_PC || generic_regnum == LLDB_REGNUM_GENERIC_RA))
+ {
+ pc_or_return_address = true;
+ }
+
lldb_private::UnwindLLDB::RegisterLocation regloc;
- if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1))
+ if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, pc_or_return_address))
{
return false;
}
@@ -1361,33 +1303,22 @@
bool
RegisterContextLLDB::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (!IsValid())
return false;
const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
- if (log && log->GetVerbose ())
- {
- log->Printf("%*sFrame %u looking for register saved location for reg %d",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsgVerbose ("looking for register saved location for reg %d", lldb_regnum);
// If this is the 0th frame, hand this over to the live register context
if (IsFrameZero ())
{
- if (log && log->GetVerbose ())
- {
- log->Printf("%*sFrame %u passing along to the live register context for reg %d",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsgVerbose ("passing along to the live register context for reg %d", lldb_regnum);
return m_thread.GetRegisterContext()->ReadRegister (reg_info, value);
}
lldb_private::UnwindLLDB::RegisterLocation regloc;
// Find out where the NEXT frame saved THIS frame's register contents
- if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1))
+ if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, false))
return false;
return ReadRegisterValueFromRegisterLocation (regloc, reg_info, value);
@@ -1396,33 +1327,22 @@
bool
RegisterContextLLDB::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value)
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (!IsValid())
return false;
const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
- if (log && log->GetVerbose ())
- {
- log->Printf("%*sFrame %u looking for register saved location for reg %d",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsgVerbose ("looking for register saved location for reg %d", lldb_regnum);
// If this is the 0th frame, hand this over to the live register context
if (IsFrameZero ())
{
- if (log && log->GetVerbose ())
- {
- log->Printf("%*sFrame %u passing along to the live register context for reg %d",
- m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
- lldb_regnum);
- }
+ UnwindLogMsgVerbose ("passing along to the live register context for reg %d", lldb_regnum);
return m_thread.GetRegisterContext()->WriteRegister (reg_info, value);
}
lldb_private::UnwindLLDB::RegisterLocation regloc;
// Find out where the NEXT frame saved THIS frame's register contents
- if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1))
+ if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1, false))
return false;
return WriteRegisterValueToRegisterLocation (regloc, reg_info, value);
@@ -1486,7 +1406,7 @@
if (!m_start_pc.IsValid())
{
- return ReadPC (start_pc);
+ return ReadPC (start_pc);
}
start_pc = m_start_pc.GetLoadAddress (CalculateTarget().get());
return true;
@@ -1507,12 +1427,12 @@
// occur if code has jumped through a NULL pointer -- we want to be able to unwind past that frame to help
// find the bug.
- if (m_all_registers_available == false
+ if (m_all_registers_available == false
&& (pc == 0 || pc == 1))
{
return false;
}
- else
+ else
{
return true;
}
@@ -1522,3 +1442,57 @@
return false;
}
}
+
+
+void
+RegisterContextLLDB::UnwindLogMsg (const char *fmt, ...)
+{
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ if (log)
+ {
+ va_list args;
+ va_start (args, fmt);
+
+ char *logmsg;
+ if (vasprintf (&logmsg, fmt, args) == -1 || logmsg == NULL)
+ {
+ if (logmsg)
+ free (logmsg);
+ va_end (args);
+ return;
+ }
+ va_end (args);
+
+ log->Printf ("%*sth%d/fr%u %s",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number,
+ logmsg);
+ free (logmsg);
+ }
+}
+
+void
+RegisterContextLLDB::UnwindLogMsgVerbose (const char *fmt, ...)
+{
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ if (log && log->GetVerbose())
+ {
+ va_list args;
+ va_start (args, fmt);
+
+ char *logmsg;
+ if (vasprintf (&logmsg, fmt, args) == -1 || logmsg == NULL)
+ {
+ if (logmsg)
+ free (logmsg);
+ va_end (args);
+ return;
+ }
+ va_end (args);
+
+ log->Printf ("%*sth%d/fr%u %s",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number,
+ logmsg);
+ free (logmsg);
+ }
+}
+
Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h Fri Oct 26 01:08:58 2012
@@ -59,7 +59,7 @@
virtual bool
WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
-
+
virtual bool
ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
@@ -96,14 +96,14 @@
friend class UnwindLLDB;
// Indicates whether this frame is frame zero -- the currently
- // executing frame -- or not.
+ // executing frame -- or not.
bool
IsFrameZero () const;
- void
+ void
InitializeZerothFrame ();
- void
+ void
InitializeNonZerothFrame();
SharedPtr
@@ -112,7 +112,7 @@
SharedPtr
GetPrevFrame () const;
- // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've got one bogus frame at frame #1.
+ // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've got one bogus frame at frame #1.
// There is a good chance we'll get back on track if we follow the frame pointer chain (or whatever is appropriate
// on this ABI) so we allow one invalid frame to be in the stack. Ideally we'll mark this frame specially at some
// point and indicate to the user that the unwinder had a hiccup. Often when this happens we will miss a frame of
@@ -124,32 +124,30 @@
// Or a frame "below" this one saved it, i.e. a function called by this one, preserved a register that this
// function didn't modify/use.
//
- // The RegisterLocation type may be set to eRegisterNotAvailable -- this will happen for a volatile register
+ // The RegisterLocation type may be set to eRegisterNotAvailable -- this will happen for a volatile register
// being queried mid-stack. Instead of floating frame 0's contents of that register up the stack (which may
// or may not be the value of that reg when the function was executing), we won't return any value.
//
// If a non-volatile register (a "preserved" register) is requested mid-stack and no frames "below" the requested
// stack have saved the register anywhere, it is safe to assume that frame 0's register values are still the same
// as the requesting frame's.
- //
- // NB this function takes a "check_next_frame" boolean which indicates whether it should call back to the
- // containing UnwindLLDB object to iterate the search down the stack (true) or if this call should look for
- // a register save for that reg in the current frame only (false). Allows UnwindLLDB to iterate through the
- // RegisterContextLLDB's instead of using recursion to find saved register values.
bool
- SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, bool check_next_frame);
+ SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc);
bool
- ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
+ ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
const lldb_private::RegisterInfo *reg_info,
lldb_private::RegisterValue &value);
bool
- WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
+ WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
const lldb_private::RegisterInfo *reg_info,
const lldb_private::RegisterValue &value);
- // Get the contents of a general purpose (address-size) register for this frame
+ void
+ InvalidateFullUnwindPlan ();
+
+ // Get the contents of a general purpose (address-size) register for this frame
// (usually retrieved from the next frame)
bool
ReadGPRValue (int register_kind, uint32_t regnum, lldb::addr_t &value);
@@ -160,8 +158,14 @@
lldb::UnwindPlanSP
GetFullUnwindPlanForFrame ();
+ void
+ UnwindLogMsg (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
+ void
+ UnwindLogMsgVerbose (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
lldb_private::Thread& m_thread;
-
+
///
// The following tell us how to retrieve the CALLER's register values (ie the "previous" frame, aka the frame above)
// i.e. where THIS frame saved them
@@ -182,7 +186,7 @@
int m_current_offset_backed_up_one; // how far into the function we've executed; -1 if unknown
// 0 if no instructions have been executed yet.
// On architectures where the return address on the stack points
- // to the instruction after the CALL, this value will have 1
+ // to the instruction after the CALL, this value will have 1
// subtracted from it. Else a function that ends in a CALL will
// have an offset pointing into the next function's address range.
// m_current_pc has the actual address of the "current" pc.
Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp Fri Oct 26 01:08:58 2012
@@ -262,14 +262,24 @@
}
bool
-UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, uint32_t starting_frame_num)
+UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, uint32_t starting_frame_num, bool pc_or_return_address_reg)
{
int64_t frame_num = starting_frame_num;
if (frame_num >= m_frames.size())
return false;
+
+ // Never interrogate more than one level while looking for the saved pc value. If the value
+ // isn't saved by frame_num, none of the frames lower on the stack will have a useful value.
+ if (pc_or_return_address_reg)
+ {
+ if (m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc))
+ return true;
+ else
+ return false;
+ }
while (frame_num >= 0)
{
- if (m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc, false))
+ if (m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc))
return true;
frame_num--;
}
Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h Fri Oct 26 01:08:58 2012
@@ -80,7 +80,7 @@
// Iterate over the RegisterContextLLDB's in our m_frames vector, look for the first one that
// has a saved location for this reg.
bool
- SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, uint32_t starting_frame_num);
+ SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, uint32_t starting_frame_num, bool pc_or_return_address_reg);
private:
Modified: lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp Fri Oct 26 01:08:58 2012
@@ -738,6 +738,8 @@
}
unwind_plan.SetSourceName ("assembly insn profiling");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes);
return true;
}
@@ -822,6 +824,9 @@
row.reset(newrow);
unwind_plan.SetPlanValidAddressRange (func);
+ unwind_plan.SetSourceName ("fast unwind assembly profiling");
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolNo);
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
return true;
}
Modified: lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp Fri Oct 26 01:08:58 2012
@@ -371,11 +371,18 @@
{
unwind_plan.SetSourceName ("eh_frame CFI");
cie_offset = current_entry + 4 - cie_offset;
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
}
else
{
unwind_plan.SetSourceName ("DWARF CFI");
+ // In theory the debug_frame info should be valid at all call sites
+ // ("asynchronous unwind info" as it is sometimes called) but in practice
+ // gcc et al all emit call frame info for the prologue and call sites, but
+ // not for the epilogue or all the other locations during the function reliably.
+ unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo);
}
+ unwind_plan.SetSourcedFromCompiler (eLazyBoolYes);
const CIE *cie = GetCIE (cie_offset);
assert (cie != NULL);
Modified: lldb/trunk/source/Symbol/FuncUnwinders.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/FuncUnwinders.cpp?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/FuncUnwinders.cpp (original)
+++ lldb/trunk/source/Symbol/FuncUnwinders.cpp Fri Oct 26 01:08:58 2012
@@ -236,3 +236,12 @@
return m_range.GetBaseAddress();
}
+void
+FuncUnwinders::InvalidateNonCallSiteUnwindPlan (lldb_private::Thread& thread)
+{
+ UnwindPlanSP arch_default = GetUnwindPlanArchitectureDefault (thread);
+ if (arch_default && m_tried_unwind_at_call_site)
+ {
+ m_unwind_plan_call_site_sp = arch_default;
+ }
+}
Modified: lldb/trunk/source/Symbol/UnwindPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/UnwindPlan.cpp?rev=166757&r1=166756&r2=166757&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/UnwindPlan.cpp (original)
+++ lldb/trunk/source/Symbol/UnwindPlan.cpp Fri Oct 26 01:08:58 2012
@@ -153,7 +153,7 @@
UnwindPlan::Row::Clear ()
{
m_offset = 0;
- m_cfa_reg_num = 0;
+ m_cfa_reg_num = LLDB_INVALID_REGNUM;
m_cfa_offset = 0;
m_register_locations.clear();
}
@@ -189,7 +189,7 @@
UnwindPlan::Row::Row() :
m_offset(0),
- m_cfa_reg_num(0),
+ m_cfa_reg_num(LLDB_INVALID_REGNUM),
m_cfa_offset(0),
m_register_locations()
{
More information about the lldb-commits
mailing list