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:
Jim Ingham 2013-01-26 02:19:28 +00:00
parent 03c66d3c57
commit 2995077d8a
22 changed files with 158 additions and 14 deletions

View File

@ -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);

View File

@ -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:

View File

@ -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
{

View File

@ -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);

View File

@ -85,6 +85,12 @@ public:
void
SetUnwindOnErrorInExpressions (bool ignore);
bool
GetStopOnSharedLibraryEvents () const;
void
SetStopOnSharedLibraryEvents (bool stop);
};
typedef STD_SHARED_PTR(ProcessProperties) ProcessPropertiesSP;

View File

@ -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.

View File

@ -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)

View File

@ -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()
{

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}

View File

@ -964,6 +964,7 @@ PlatformDarwin::SetThreadCreationBreakpoint (Target &target)
eFunctionNameTypeFull,
skip_prologue,
internal);
bp_sp->SetBreakpointKind("thread-creation");
return bp_sp;
}

View File

@ -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;
}

View File

@ -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
{

View File

@ -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());

View File

@ -93,6 +93,7 @@ ThreadPlanRunToAddress::SetInitialBreakpoints ()
{
m_break_ids[i] = breakpoint->GetID();
breakpoint->SetThreadID(m_thread.GetID());
breakpoint->SetBreakpointKind("run-to-address");
}
}
}

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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
{