summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2014-02-14 05:06:49 +0000
committerJason Molenda <jmolenda@apple.com>2014-02-14 05:06:49 +0000
commita4bea72ee72a8e477e9f6fd139ad24754efeac02 (patch)
treea561e13249c1d23f9504d6106199ad824a88ce20
parent293349e4d786d5f1561bd057f94d54cd90c00aed (diff)
downloadbcm5719-llvm-a4bea72ee72a8e477e9f6fd139ad24754efeac02.tar.gz
bcm5719-llvm-a4bea72ee72a8e477e9f6fd139ad24754efeac02.zip
Add a new target setting, trap-handler-names, where a user can
specify a list of functions which should be treated as trap handlers. This will be primarily useful to people working in non-user-level process debugging - kernels and other standalone environments. For most people, the trap handler functions provided by the Platform plugin will be sufficient. <rdar://problem/15835846>, <rdar://problem/15982682> llvm-svn: 201386
-rw-r--r--lldb/include/lldb/Target/Target.h5
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp69
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h13
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp15
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.h20
-rw-r--r--lldb/source/Target/Target.cpp16
6 files changed, 110 insertions, 28 deletions
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 75fd1d9703b..e65a511ab77 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -177,6 +177,11 @@ public:
MemoryModuleLoadLevel
GetMemoryModuleLoadLevel() const;
+ bool
+ GetUserSpecifiedTrapHandlerNames (Args &args) const;
+
+ void
+ SetUserSpecifiedTrapHandlerNames (const Args &args);
};
typedef std::shared_ptr<TargetProperties> TargetPropertiesSP;
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 3f4c6609a52..f87db581074 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -172,21 +172,15 @@ RegisterContextLLDB::InitializeZerothFrame()
AddressRange addr_range;
m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range);
- m_frame_type = eNormalFrame;
- PlatformSP platform_sp (process->GetTarget().GetPlatform());
- if (platform_sp)
+ if (IsTrapHandlerSymbol (process, m_sym_ctx))
{
- const std::vector<ConstString> trap_handler_names (platform_sp->GetTrapHandlerSymbolNames());
- for (ConstString name : trap_handler_names)
- {
- if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
- (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name))
- {
- m_frame_type = eTrapHandlerFrame;
- }
- }
+ m_frame_type = eTrapHandlerFrame;
+ }
+ else
+ {
+ // FIXME: Detect eDebuggerFrame here.
+ m_frame_type = eNormalFrame;
}
- // FIXME: Detect eDebuggerFrame here.
// If we were able to find a symbol/function, set addr_range to the bounds of that symbol/function.
// else treat the current pc value as the start_pc and record no offset.
@@ -497,25 +491,18 @@ RegisterContextLLDB::InitializeNonZerothFrame()
m_current_offset_backed_up_one = -1;
}
- if (m_frame_type != eSkipFrame) // don't override eSkipFrame
+ if (IsTrapHandlerSymbol (process, m_sym_ctx))
{
- m_frame_type = eNormalFrame;
+ m_frame_type = eTrapHandlerFrame;
}
- PlatformSP platform_sp (process->GetTarget().GetPlatform());
- if (platform_sp)
+ else
{
- const std::vector<ConstString> trap_handler_names (platform_sp->GetTrapHandlerSymbolNames());
- for (ConstString name : trap_handler_names)
+ // FIXME: Detect eDebuggerFrame here.
+ if (m_frame_type != eSkipFrame) // don't override eSkipFrame
{
- if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
- (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name))
- {
- m_frame_type = eTrapHandlerFrame;
- }
+ m_frame_type = eNormalFrame;
}
}
- // FIXME: Detect eDebuggerFrame here.
-
// We've set m_frame_type and m_sym_ctx before this call.
m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
@@ -1010,6 +997,35 @@ RegisterContextLLDB::IsSkipFrame () const
return m_frame_type == eSkipFrame;
}
+bool
+RegisterContextLLDB::IsTrapHandlerSymbol (lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const
+{
+ PlatformSP platform_sp (process->GetTarget().GetPlatform());
+ if (platform_sp)
+ {
+ const std::vector<ConstString> trap_handler_names (platform_sp->GetTrapHandlerSymbolNames());
+ for (ConstString name : trap_handler_names)
+ {
+ if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
+ (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name))
+ {
+ return true;
+ }
+ }
+ }
+ const std::vector<ConstString> user_specified_trap_handler_names (m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames());
+ for (ConstString name : user_specified_trap_handler_names)
+ {
+ if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
+ (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
// Answer the question: Where did THIS frame save the CALLER frame ("previous" frame)'s register value?
enum UnwindLLDB::RegisterSearchResult
@@ -1633,3 +1649,4 @@ RegisterContextLLDB::UnwindLogMsgVerbose (const char *fmt, ...)
}
}
+
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
index 505457260da..bf9dd9a2931 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -123,6 +123,19 @@ private:
bool
IsSkipFrame () const;
+
+ //------------------------------------------------------------------
+ /// Determines if a SymbolContext is a trap handler or not
+ ///
+ /// Given a SymbolContext, determines if this is a trap handler function
+ /// aka asynchronous signal handler.
+ ///
+ /// @return
+ /// Returns true if the SymbolContext is a trap handler.
+ //------------------------------------------------------------------
+ bool
+ IsTrapHandlerSymbol (lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const;
+
// Provide a location for where THIS function saved the CALLER's register value
// 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.
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 36223db8186..a3a7002ea09 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -26,8 +26,21 @@ using namespace lldb_private;
UnwindLLDB::UnwindLLDB (Thread &thread) :
Unwind (thread),
m_frames(),
- m_unwind_complete(false)
+ m_unwind_complete(false),
+ m_user_supplied_trap_handler_functions()
{
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp)
+ {
+ Args args;
+ process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames (args);
+ size_t count = args.GetArgumentCount();
+ for (size_t i = 0; i < count; i++)
+ {
+ const char *func_name = args.GetArgumentAtIndex(i);
+ m_user_supplied_trap_handler_functions.push_back (ConstString (func_name));
+ }
+ }
}
uint32_t
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
index 5725654a686..eb5400389df 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -13,6 +13,7 @@
#include <vector>
#include "lldb/lldb-public.h"
+#include "lldb/Core/ConstString.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/RegisterContext.h"
@@ -90,6 +91,24 @@ protected:
SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num, bool pc_register);
+ //------------------------------------------------------------------
+ /// Provide the list of user-specified trap handler functions
+ ///
+ /// The Platform is one source of trap handler function names; that
+ /// may be augmented via a setting. The setting needs to be converted
+ /// into an array of ConstStrings before it can be used - we only want
+ /// to do that once per thread so it's here in the UnwindLLDB object.
+ ///
+ /// @return
+ /// Vector of ConstStrings of trap handler function names. May be
+ /// empty.
+ //------------------------------------------------------------------
+ const std::vector<ConstString> &
+ GetUserSpecifiedTrapHandlerFunctionNames ()
+ {
+ return m_user_supplied_trap_handler_functions;
+ }
+
private:
struct Cursor
@@ -110,6 +129,7 @@ private:
// number of frames, etc. Otherwise we've only gone as far as directly asked, and m_frames.size()
// is how far we've currently gone.
+ std::vector<ConstString> m_user_supplied_trap_handler_functions;
bool AddOneMoreFrame (ABI *abi);
bool AddFirstFrame ();
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 3a980251ef6..e7816266b41 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -2638,6 +2638,7 @@ g_properties[] =
"'partial' will load sections and attempt to find function bounds without downloading the symbol table (faster, still accurate, missing symbol names). "
"'minimal' is the fastest setting and will load section data with no symbols, but should rarely be used as stack frames in these memory regions will be inaccurate and not provide any context (fastest). " },
{ "display-expression-in-crashlogs" , OptionValue::eTypeBoolean , false, false, NULL, NULL, "Expressions that crash will show up in crash logs if the host system supports executable specific crash log strings and this setting is set to true." },
+ { "trap-handler-names" , OptionValue::eTypeArray , true, OptionValue::eTypeString, NULL, NULL, "A list of trap handler function names, e.g. a common Unix user process one is _sigtramp." },
{ NULL , OptionValue::eTypeInvalid , false, 0 , NULL, NULL, NULL }
};
enum
@@ -2670,7 +2671,8 @@ enum
ePropertyUseFastStepping,
ePropertyLoadScriptFromSymbolFile,
ePropertyMemoryModuleLoadLevel,
- ePropertyDisplayExpressionsInCrashlogs
+ ePropertyDisplayExpressionsInCrashlogs,
+ ePropertyTrapHandlerNames
};
@@ -3077,7 +3079,19 @@ TargetProperties::GetMemoryModuleLoadLevel() const
return (MemoryModuleLoadLevel)m_collection_sp->GetPropertyAtIndexAsEnumeration(NULL, idx, g_properties[idx].default_uint_value);
}
+bool
+TargetProperties::GetUserSpecifiedTrapHandlerNames (Args &args) const
+{
+ const uint32_t idx = ePropertyTrapHandlerNames;
+ return m_collection_sp->GetPropertyAtIndexAsArgs (NULL, idx, args);
+}
+void
+TargetProperties::SetUserSpecifiedTrapHandlerNames (const Args &args)
+{
+ const uint32_t idx = ePropertyTrapHandlerNames;
+ m_collection_sp->SetPropertyAtIndexFromArgs (NULL, idx, args);
+}
//----------------------------------------------------------------------
// Target::TargetEventData
OpenPOWER on IntegriCloud