Add "target.process.stop-on-shared-library-events" setting, and make it work.
Add the ability to give breakpoints a "kind" string, and have the StopInfoBreakpoint print that in the brief description if set. Also print the kind - if set - in the breakpoint listing. Give kinds to a bunch of the internal breakpoints. We were deleting the Mac OS X dynamic loader breakpoint as though the id we had stored away was a breakpoint site ID, but in fact it was a breakpoint id, so we never actually deleted it. Fixed that. llvm-svn: 173555
This commit is contained in:
parent
03c66d3c57
commit
2995077d8a
|
@ -488,6 +488,32 @@ public:
|
|||
void
|
||||
GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations = false);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set the "kind" description for a breakpoint. If the breakpoint is hit
|
||||
/// the stop info will show this "kind" description instead of the breakpoint
|
||||
/// number. Mostly useful for internal breakpoints, where the breakpoint number
|
||||
/// doesn't have meaning to the user.
|
||||
///
|
||||
/// @param[in] kind
|
||||
/// New "kind" description.
|
||||
//------------------------------------------------------------------
|
||||
void
|
||||
SetBreakpointKind (const char *kind)
|
||||
{
|
||||
m_kind_description.assign (kind);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the "kind" description for a breakpoint.
|
||||
///
|
||||
/// @return
|
||||
/// The breakpoint kind, or NULL if none is set.
|
||||
//------------------------------------------------------------------
|
||||
const char *GetBreakpointKind () const
|
||||
{
|
||||
return m_kind_description.c_str();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Accessor for the breakpoint Target.
|
||||
/// @return
|
||||
|
@ -588,6 +614,7 @@ private:
|
|||
lldb::BreakpointResolverSP m_resolver_sp; // The resolver that defines this breakpoint.
|
||||
BreakpointOptions m_options; // Settable breakpoint options
|
||||
BreakpointLocationList m_locations; // The list of locations currently found for this breakpoint.
|
||||
std::string m_kind_description;
|
||||
|
||||
void
|
||||
SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind);
|
||||
|
|
|
@ -171,6 +171,14 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
bool ValidForThisThread (Thread *thread);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tell whether ALL the breakpoints in the location collection are internal.
|
||||
///
|
||||
/// @result
|
||||
/// \b true if all breakpoint locations are owned by internal breakpoints,
|
||||
/// \b false otherwise.
|
||||
//------------------------------------------------------------------
|
||||
bool IsInternal() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
|
|
@ -220,9 +220,29 @@ public:
|
|||
GetDescription (Stream *s,
|
||||
lldb::DescriptionLevel level);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tell whether a breakpoint has a location at this site.
|
||||
///
|
||||
/// @param[in] bp_id
|
||||
/// The breakpoint id to query.
|
||||
///
|
||||
/// @result
|
||||
/// \b true if bp_id has a location that is at this site,
|
||||
/// \b false otherwise.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
IsBreakpointAtThisSite (lldb::break_id_t bp_id);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tell whether ALL the breakpoints in the location collection are internal.
|
||||
///
|
||||
/// @result
|
||||
/// \b true if all breakpoint locations are owned by internal breakpoints,
|
||||
/// \b false otherwise.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
IsInternal () const;
|
||||
|
||||
BreakpointSite::Type
|
||||
GetType () const
|
||||
{
|
||||
|
|
|
@ -229,7 +229,6 @@ protected:
|
|||
// Member variables.
|
||||
//------------------------------------------------------------------
|
||||
Process* m_process; ///< The process that this dynamic loader plug-in is tracking.
|
||||
bool m_stop_when_images_change; ///< Boolean value that indicates if the process should stop when imamges change.
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (DynamicLoader);
|
||||
|
||||
|
|
|
@ -85,6 +85,12 @@ public:
|
|||
|
||||
void
|
||||
SetUnwindOnErrorInExpressions (bool ignore);
|
||||
|
||||
bool
|
||||
GetStopOnSharedLibraryEvents () const;
|
||||
|
||||
void
|
||||
SetStopOnSharedLibraryEvents (bool stop);
|
||||
};
|
||||
|
||||
typedef STD_SHARED_PTR(ProcessProperties) ProcessPropertiesSP;
|
||||
|
|
|
@ -525,12 +525,21 @@ Breakpoint::GetNumLocations() const
|
|||
void
|
||||
Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
|
||||
{
|
||||
const size_t num_locations = GetNumLocations ();
|
||||
const size_t num_resolved_locations = GetNumResolvedLocations ();
|
||||
|
||||
assert (s != NULL);
|
||||
|
||||
if (!m_kind_description.empty())
|
||||
{
|
||||
if (eDescriptionLevelBrief)
|
||||
{
|
||||
s->PutCString (GetBreakpointKind());
|
||||
return;
|
||||
}
|
||||
else
|
||||
s->Printf("Kind: %s\n", GetBreakpointKind ());
|
||||
}
|
||||
|
||||
const size_t num_locations = GetNumLocations ();
|
||||
const size_t num_resolved_locations = GetNumResolvedLocations ();
|
||||
|
||||
// They just made the breakpoint, they don't need to be told HOW they made it...
|
||||
// Also, we'll print the breakpoint number differently depending on whether there is 1 or more locations.
|
||||
|
|
|
@ -162,6 +162,25 @@ BreakpointLocationCollection::ValidForThisThread (Thread *thread)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
BreakpointLocationCollection::IsInternal () const
|
||||
{
|
||||
collection::const_iterator pos,
|
||||
begin = m_break_loc_collection.begin(),
|
||||
end = m_break_loc_collection.end();
|
||||
|
||||
bool is_internal = true;
|
||||
|
||||
for (pos = begin; pos != end; ++pos)
|
||||
{
|
||||
if (!(*pos)->GetBreakpoint().IsInternal ())
|
||||
{
|
||||
is_internal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return is_internal;
|
||||
}
|
||||
|
||||
void
|
||||
BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
||||
|
|
|
@ -98,6 +98,12 @@ BreakpointSite::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
|||
m_owners.GetDescription (s, level);
|
||||
}
|
||||
|
||||
bool
|
||||
BreakpointSite::IsInternal() const
|
||||
{
|
||||
return m_owners.IsInternal();
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
BreakpointSite::GetTrapOpcodeBytes()
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Target/DynamicLoader.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
@ -45,8 +46,7 @@ DynamicLoader::FindPlugin (Process *process, const char *plugin_name)
|
|||
// DynamicLoader constructor
|
||||
//----------------------------------------------------------------------
|
||||
DynamicLoader::DynamicLoader(Process *process) :
|
||||
m_process (process),
|
||||
m_stop_when_images_change(false) // Stop the process by default when a process' images change
|
||||
m_process (process)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -64,12 +64,12 @@ DynamicLoader::~DynamicLoader()
|
|||
bool
|
||||
DynamicLoader::GetStopWhenImagesChange () const
|
||||
{
|
||||
return m_stop_when_images_change;
|
||||
return m_process->GetStopOnSharedLibraryEvents();
|
||||
}
|
||||
|
||||
void
|
||||
DynamicLoader::SetStopWhenImagesChange (bool stop)
|
||||
{
|
||||
m_stop_when_images_change = stop;
|
||||
m_process->SetStopOnSharedLibraryEvents (stop);
|
||||
}
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ DynamicLoaderMacOSXDYLD::Clear (bool clear_process)
|
|||
Mutex::Locker locker(m_mutex);
|
||||
|
||||
if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
|
||||
m_process->ClearBreakpointSiteByID(m_break_id);
|
||||
m_process->GetTarget().RemoveBreakpointByID (m_break_id);
|
||||
|
||||
if (clear_process)
|
||||
m_process = NULL;
|
||||
|
@ -1565,6 +1565,7 @@ DynamicLoaderMacOSXDYLD::SetNotificationBreakpoint ()
|
|||
{
|
||||
Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
|
||||
dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
|
||||
dyld_break->SetBreakpointKind ("shared-library-event");
|
||||
m_break_id = dyld_break->GetID();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -202,6 +202,7 @@ DynamicLoaderPOSIXDYLD::ProbeEntry()
|
|||
|
||||
entry_break = m_process->GetTarget().CreateBreakpoint(entry, true).get();
|
||||
entry_break->SetCallback(EntryBreakpointHit, this, true);
|
||||
entry_break->SetBreakpointKind("shared-library-event");
|
||||
}
|
||||
|
||||
// The runtime linker has run and initialized the rendezvous structure once the
|
||||
|
@ -233,6 +234,7 @@ DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint()
|
|||
break_addr = m_rendezvous.GetBreakAddress();
|
||||
dyld_break = m_process->GetTarget().CreateBreakpoint(break_addr, true).get();
|
||||
dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
|
||||
dyld_break->SetBreakpointKind ("shared-library-event");
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -418,6 +418,7 @@ ItaniumABILanguageRuntime::SetExceptionBreakpoints ()
|
|||
SearchFilterSP filter_sp = target.GetSearchFilterForModule(NULL);
|
||||
|
||||
m_cxx_exception_bp_sp = target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal);
|
||||
m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
|
||||
}
|
||||
else
|
||||
m_cxx_exception_bp_sp->SetEnabled (true);
|
||||
|
|
|
@ -382,6 +382,7 @@ AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols ()
|
|||
{
|
||||
m_trampolines_changed_bp_id = trampolines_changed_bp_sp->GetID();
|
||||
trampolines_changed_bp_sp->SetCallback (RefreshTrampolines, this, true);
|
||||
trampolines_changed_bp_sp->SetBreakpointKind ("objc-trampolines-changed");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -964,6 +964,7 @@ PlatformDarwin::SetThreadCreationBreakpoint (Target &target)
|
|||
eFunctionNameTypeFull,
|
||||
skip_prologue,
|
||||
internal);
|
||||
bp_sp->SetBreakpointKind("thread-creation");
|
||||
|
||||
return bp_sp;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@ LanguageRuntime::CreateExceptionBreakpoint(
|
|||
SearchFilterSP filter_sp(target.GetSearchFilterForModule(NULL));
|
||||
|
||||
exc_breakpt_sp = target.CreateBreakpoint (filter_sp, resolver_sp, is_internal);
|
||||
if (is_internal)
|
||||
exc_breakpt_sp->SetBreakpointKind("exception");
|
||||
|
||||
return exc_breakpt_sp;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ g_properties[] =
|
|||
{ "ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, breakpoints will be ignored during expression evaluation." },
|
||||
{ "unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, errors in expression evaluation will unwind the stack back to the state before the call." },
|
||||
{ "python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, NULL, NULL, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." },
|
||||
{ "stop-on-sharedlibrary-events" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, stop when a shared library is loaded or unloaded." },
|
||||
{ NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -108,7 +109,8 @@ enum {
|
|||
ePropertyExtraStartCommand,
|
||||
ePropertyIgnoreBreakpointsInExpressions,
|
||||
ePropertyUnwindOnErrorInExpressions,
|
||||
ePropertyPythonOSPluginPath
|
||||
ePropertyPythonOSPluginPath,
|
||||
ePropertyStopOnSharedLibraryEvents
|
||||
};
|
||||
|
||||
ProcessProperties::ProcessProperties (bool is_global) :
|
||||
|
@ -119,7 +121,7 @@ ProcessProperties::ProcessProperties (bool is_global) :
|
|||
m_collection_sp.reset (new ProcessOptionValueProperties(ConstString("process")));
|
||||
m_collection_sp->Initialize(g_properties);
|
||||
m_collection_sp->AppendProperty(ConstString("thread"),
|
||||
ConstString("Settings specify to threads."),
|
||||
ConstString("Settings specific to threads."),
|
||||
true,
|
||||
Thread::GetGlobalProperties()->GetValueProperties());
|
||||
}
|
||||
|
@ -197,6 +199,20 @@ ProcessProperties::SetUnwindOnErrorInExpressions (bool ignore)
|
|||
m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore);
|
||||
}
|
||||
|
||||
bool
|
||||
ProcessProperties::GetStopOnSharedLibraryEvents () const
|
||||
{
|
||||
const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
|
||||
return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
|
||||
}
|
||||
|
||||
void
|
||||
ProcessProperties::SetStopOnSharedLibraryEvents (bool stop)
|
||||
{
|
||||
const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
|
||||
m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop);
|
||||
}
|
||||
|
||||
void
|
||||
ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
|
||||
{
|
||||
|
|
|
@ -206,6 +206,22 @@ public:
|
|||
if (bp_site_sp)
|
||||
{
|
||||
StreamString strm;
|
||||
// If we have just hit an internal breakpoint, and it has a kind description, print that instead of the
|
||||
// full breakpoint printing:
|
||||
if (bp_site_sp->IsInternal())
|
||||
{
|
||||
size_t num_owners = bp_site_sp->GetNumberOfOwners();
|
||||
for (size_t idx = 0; idx < num_owners; idx++)
|
||||
{
|
||||
const char *kind = bp_site_sp->GetOwnerAtIndex(idx)->GetBreakpoint().GetBreakpointKind();
|
||||
if (kind != NULL)
|
||||
{
|
||||
m_description.assign (kind);
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strm.Printf("breakpoint ");
|
||||
bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
|
||||
m_description.swap (strm.GetString());
|
||||
|
|
|
@ -93,6 +93,7 @@ ThreadPlanRunToAddress::SetInitialBreakpoints ()
|
|||
{
|
||||
m_break_ids[i] = breakpoint->GetID();
|
||||
breakpoint->SetThreadID(m_thread.GetID());
|
||||
breakpoint->SetBreakpointKind("run-to-address");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,6 +107,7 @@ ThreadPlanStepOut::ThreadPlanStepOut
|
|||
{
|
||||
return_bp->SetThreadID(m_thread.GetID());
|
||||
m_return_bp_id = return_bp->GetID();
|
||||
return_bp->SetBreakpointKind ("step-out");
|
||||
}
|
||||
|
||||
if (immediate_return_from_sp)
|
||||
|
|
|
@ -334,8 +334,13 @@ ThreadPlanStepRange::SetNextBranchBreakpoint ()
|
|||
const bool is_internal = true;
|
||||
run_to_address = instructions->GetInstructionAtIndex(branch_index)->GetAddress();
|
||||
m_next_branch_bp_sp = GetTarget().CreateBreakpoint(run_to_address, is_internal);
|
||||
m_next_branch_bp_sp->SetThreadID(m_thread.GetID());
|
||||
return true;
|
||||
if (m_next_branch_bp_sp)
|
||||
{
|
||||
m_next_branch_bp_sp->SetThreadID(m_thread.GetID());
|
||||
m_next_branch_bp_sp->SetBreakpointKind ("next-branch-location");
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -61,6 +61,7 @@ ThreadPlanStepThrough::ThreadPlanStepThrough (Thread &thread, StackID &m_stack_i
|
|||
{
|
||||
return_bp->SetThreadID(m_thread.GetID());
|
||||
m_backstop_bkpt_id = return_bp->GetID();
|
||||
return_bp->SetBreakpointKind("step-through-backstop");
|
||||
}
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
if (log)
|
||||
|
|
|
@ -73,6 +73,7 @@ ThreadPlanStepUntil::ThreadPlanStepUntil
|
|||
{
|
||||
return_bp->SetThreadID(thread_id);
|
||||
m_return_bp_id = return_bp->GetID();
|
||||
return_bp->SetBreakpointKind ("until-return-backstop");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,6 +87,7 @@ ThreadPlanStepUntil::ThreadPlanStepUntil
|
|||
{
|
||||
until_bp->SetThreadID(thread_id);
|
||||
m_until_points[address_list[i]] = until_bp->GetID();
|
||||
until_bp->SetBreakpointKind("until-target");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue