2010-06-09 00:52:24 +08:00
|
|
|
//===-- BreakpointLocation.cpp ----------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
// C Includes
|
|
|
|
// C++ Includes
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
// Other libraries and framework includes
|
|
|
|
// Project includes
|
|
|
|
#include "lldb/Breakpoint/BreakpointLocation.h"
|
|
|
|
#include "lldb/Breakpoint/BreakpointID.h"
|
|
|
|
#include "lldb/Breakpoint/StoppointCallbackContext.h"
|
2011-06-03 07:58:26 +08:00
|
|
|
#include "lldb/Core/Debugger.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Core/Log.h"
|
|
|
|
#include "lldb/Target/Target.h"
|
2010-10-15 07:45:03 +08:00
|
|
|
#include "lldb/Target/ThreadPlan.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Target/Process.h"
|
|
|
|
#include "lldb/Core/StreamString.h"
|
|
|
|
#include "lldb/lldb-private-log.h"
|
|
|
|
#include "lldb/Target/Thread.h"
|
2010-06-16 10:00:15 +08:00
|
|
|
#include "lldb/Target/ThreadSpec.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
|
|
BreakpointLocation::BreakpointLocation
|
|
|
|
(
|
|
|
|
break_id_t loc_id,
|
|
|
|
Breakpoint &owner,
|
2011-02-05 08:38:04 +08:00
|
|
|
const Address &addr,
|
2010-06-09 00:52:24 +08:00
|
|
|
lldb::tid_t tid,
|
|
|
|
bool hardware
|
|
|
|
) :
|
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
2011-05-23 06:46:53 +08:00
|
|
|
StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
|
2010-06-09 00:52:24 +08:00
|
|
|
m_address (addr),
|
|
|
|
m_owner (owner),
|
|
|
|
m_options_ap (),
|
|
|
|
m_bp_site_sp ()
|
|
|
|
{
|
2010-06-16 10:00:15 +08:00
|
|
|
SetThreadID (tid);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
BreakpointLocation::~BreakpointLocation()
|
|
|
|
{
|
|
|
|
ClearBreakpointSite();
|
|
|
|
}
|
|
|
|
|
|
|
|
lldb::addr_t
|
2010-06-14 12:18:27 +08:00
|
|
|
BreakpointLocation::GetLoadAddress () const
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
2011-05-23 06:46:53 +08:00
|
|
|
return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Address &
|
|
|
|
BreakpointLocation::GetAddress ()
|
|
|
|
{
|
|
|
|
return m_address;
|
|
|
|
}
|
|
|
|
|
|
|
|
Breakpoint &
|
|
|
|
BreakpointLocation::GetBreakpoint ()
|
|
|
|
{
|
|
|
|
return m_owner;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2012-02-02 03:05:20 +08:00
|
|
|
BreakpointLocation::IsEnabled () const
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2012-01-31 06:48:10 +08:00
|
|
|
if (!m_owner.IsEnabled())
|
|
|
|
return false;
|
|
|
|
else if (m_options_ap.get() != NULL)
|
2010-06-09 00:52:24 +08:00
|
|
|
return m_options_ap->IsEnabled();
|
|
|
|
else
|
2012-01-31 06:48:10 +08:00
|
|
|
return true;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BreakpointLocation::SetEnabled (bool enabled)
|
|
|
|
{
|
|
|
|
GetLocationOptions()->SetEnabled(enabled);
|
|
|
|
if (enabled)
|
|
|
|
{
|
|
|
|
ResolveBreakpointSite();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ClearBreakpointSite();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
|
|
|
|
{
|
2010-06-16 10:00:15 +08:00
|
|
|
if (thread_id != LLDB_INVALID_THREAD_ID)
|
|
|
|
GetLocationOptions()->SetThreadID(thread_id);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// If we're resetting this to an invalid thread id, then
|
|
|
|
// don't make an options pointer just to do that.
|
|
|
|
if (m_options_ap.get() != NULL)
|
|
|
|
m_options_ap->SetThreadID (thread_id);
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
|
|
|
|
{
|
2010-06-18 09:00:58 +08:00
|
|
|
if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
|
2010-06-09 00:52:24 +08:00
|
|
|
return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
|
2010-06-18 09:00:58 +08:00
|
|
|
else
|
|
|
|
return m_owner.InvokeCallback (context, GetID());
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
|
|
|
|
bool is_synchronous)
|
|
|
|
{
|
|
|
|
// The default "Baton" class will keep a copy of "baton" and won't free
|
|
|
|
// or delete it when it goes goes out of scope.
|
|
|
|
GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
|
|
|
|
bool is_synchronous)
|
|
|
|
{
|
|
|
|
GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
|
|
|
|
}
|
|
|
|
|
2010-10-15 07:45:03 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
void
|
|
|
|
BreakpointLocation::ClearCallback ()
|
|
|
|
{
|
|
|
|
GetLocationOptions()->ClearCallback();
|
|
|
|
}
|
|
|
|
|
2010-10-15 07:45:03 +08:00
|
|
|
void
|
|
|
|
BreakpointLocation::SetCondition (const char *condition)
|
|
|
|
{
|
|
|
|
GetLocationOptions()->SetCondition (condition);
|
|
|
|
}
|
|
|
|
|
|
|
|
ThreadPlan *
|
|
|
|
BreakpointLocation::GetThreadPlanToTestCondition (ExecutionContext &exe_ctx, Stream &error)
|
|
|
|
{
|
|
|
|
if (m_options_ap.get())
|
2012-01-30 04:56:30 +08:00
|
|
|
return m_options_ap->GetThreadPlanToTestCondition (exe_ctx, shared_from_this(), error);
|
2010-10-15 07:45:03 +08:00
|
|
|
else
|
2012-01-30 04:56:30 +08:00
|
|
|
return m_owner.GetThreadPlanToTestCondition (exe_ctx, shared_from_this(), error);
|
2010-10-15 07:45:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
2011-06-16 05:16:00 +08:00
|
|
|
BreakpointLocation::GetConditionText () const
|
2010-10-15 07:45:03 +08:00
|
|
|
{
|
2011-06-16 05:16:00 +08:00
|
|
|
return GetOptionsNoCreate()->GetConditionText();
|
2010-10-15 07:45:03 +08:00
|
|
|
}
|
|
|
|
|
2010-07-10 04:39:50 +08:00
|
|
|
uint32_t
|
2010-06-09 00:52:24 +08:00
|
|
|
BreakpointLocation::GetIgnoreCount ()
|
|
|
|
{
|
2010-06-23 05:12:54 +08:00
|
|
|
return GetOptionsNoCreate()->GetIgnoreCount();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2010-07-10 04:39:50 +08:00
|
|
|
BreakpointLocation::SetIgnoreCount (uint32_t n)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
GetLocationOptions()->SetIgnoreCount(n);
|
|
|
|
}
|
|
|
|
|
2010-06-16 10:00:15 +08:00
|
|
|
const BreakpointOptions *
|
2010-06-23 05:12:54 +08:00
|
|
|
BreakpointLocation::GetOptionsNoCreate () const
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
|
|
|
if (m_options_ap.get() != NULL)
|
|
|
|
return m_options_ap.get();
|
|
|
|
else
|
|
|
|
return m_owner.GetOptions ();
|
|
|
|
}
|
|
|
|
|
|
|
|
BreakpointOptions *
|
|
|
|
BreakpointLocation::GetLocationOptions ()
|
|
|
|
{
|
2010-06-18 09:00:58 +08:00
|
|
|
// If we make the copy we don't copy the callbacks because that is potentially
|
|
|
|
// expensive and we don't want to do that for the simple case where someone is
|
|
|
|
// just disabling the location.
|
2010-06-09 00:52:24 +08:00
|
|
|
if (m_options_ap.get() == NULL)
|
2010-06-18 09:00:58 +08:00
|
|
|
m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
return m_options_ap.get();
|
|
|
|
}
|
|
|
|
|
2010-06-16 10:00:15 +08:00
|
|
|
bool
|
|
|
|
BreakpointLocation::ValidForThisThread (Thread *thread)
|
|
|
|
{
|
2010-06-23 05:12:54 +08:00
|
|
|
return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
|
2010-06-16 10:00:15 +08:00
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
// RETURNS - true if we should stop at this breakpoint, false if we
|
2010-06-16 10:00:15 +08:00
|
|
|
// should continue. Note, we don't check the thread spec for the breakpoint
|
|
|
|
// here, since if the breakpoint is not for this thread, then the event won't
|
|
|
|
// even get reported, so the check is redundant.
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
bool
|
|
|
|
BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
|
|
|
|
{
|
|
|
|
bool should_stop = true;
|
2010-11-06 09:53:30 +08:00
|
|
|
LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2012-01-24 07:03:59 +08:00
|
|
|
IncrementHitCount();
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
if (!IsEnabled())
|
|
|
|
return false;
|
|
|
|
|
2012-01-24 07:03:59 +08:00
|
|
|
if (GetHitCount() <= GetIgnoreCount())
|
2010-06-09 00:52:24 +08:00
|
|
|
return false;
|
|
|
|
|
2010-10-15 07:45:03 +08:00
|
|
|
// We only run synchronous callbacks in ShouldStop:
|
2010-06-09 00:52:24 +08:00
|
|
|
context->is_synchronous = true;
|
|
|
|
should_stop = InvokeCallback (context);
|
2010-10-15 07:45:03 +08:00
|
|
|
|
2011-06-03 07:58:26 +08:00
|
|
|
if (log)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2011-06-03 07:58:26 +08:00
|
|
|
StreamString s;
|
|
|
|
GetDescription (&s, lldb::eDescriptionLevelVerbose);
|
|
|
|
log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2011-06-03 07:58:26 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
return should_stop;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
BreakpointLocation::IsResolved () const
|
|
|
|
{
|
|
|
|
return m_bp_site_sp.get() != NULL;
|
|
|
|
}
|
|
|
|
|
2010-10-15 07:45:03 +08:00
|
|
|
lldb::BreakpointSiteSP
|
|
|
|
BreakpointLocation::GetBreakpointSite() const
|
|
|
|
{
|
|
|
|
return m_bp_site_sp;
|
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
bool
|
|
|
|
BreakpointLocation::ResolveBreakpointSite ()
|
|
|
|
{
|
|
|
|
if (m_bp_site_sp)
|
|
|
|
return true;
|
|
|
|
|
2010-09-15 07:36:40 +08:00
|
|
|
Process *process = m_owner.GetTarget().GetProcessSP().get();
|
2010-06-09 00:52:24 +08:00
|
|
|
if (process == NULL)
|
|
|
|
return false;
|
|
|
|
|
2010-09-15 07:36:40 +08:00
|
|
|
if (m_owner.GetTarget().GetSectionLoadList().IsEmpty())
|
|
|
|
return false;
|
|
|
|
|
2012-01-30 04:56:30 +08:00
|
|
|
lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), false);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2010-07-17 08:56:13 +08:00
|
|
|
if (new_id == LLDB_INVALID_BREAK_ID)
|
2010-06-09 00:52:24 +08:00
|
|
|
{
|
2010-11-06 09:53:30 +08:00
|
|
|
LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
|
2010-06-09 00:52:24 +08:00
|
|
|
if (log)
|
|
|
|
log->Warning ("Tried to add breakpoint site at 0x%llx but it was already present.\n",
|
Added new lldb_private::Process memory read/write functions to stop a bunch
of duplicated code from appearing all over LLDB:
lldb::addr_t
Process::ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error);
bool
Process::WritePointerToMemory (lldb::addr_t vm_addr, lldb::addr_t ptr_value, Error &error);
size_t
Process::ReadScalarIntegerFromMemory (lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Error &error);
size_t
Process::WriteScalarToMemory (lldb::addr_t vm_addr, const Scalar &scalar, uint32_t size, Error &error);
in lldb_private::Process the following functions were renamed:
From:
uint64_t
Process::ReadUnsignedInteger (lldb::addr_t load_addr,
size_t byte_size,
Error &error);
To:
uint64_t
Process::ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr,
size_t byte_size,
uint64_t fail_value,
Error &error);
Cleaned up a lot of code that was manually doing what the above functions do
to use the functions listed above.
Added the ability to get a scalar value as a buffer that can be written down
to a process (byte swapping the Scalar value if needed):
uint32_t
Scalar::GetAsMemoryData (void *dst,
uint32_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
The "dst_len" can be smaller that the size of the scalar and the least
significant bytes will be written. "dst_len" can also be larger and the
most significant bytes will be padded with zeroes.
Centralized the code that adds or removes address bits for callable and opcode
addresses into lldb_private::Target:
lldb::addr_t
Target::GetCallableLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
lldb::addr_t
Target::GetOpcodeLoadAddress (lldb::addr_t load_addr, AddressClass addr_class) const;
All necessary lldb_private::Address functions now use the target versions so
changes should only need to happen in one place if anything needs updating.
Fixed up a lot of places that were calling :
addr_t
Address::GetLoadAddress(Target*);
to call the Address::GetCallableLoadAddress() or Address::GetOpcodeLoadAddress()
as needed. There were many places in the breakpoint code where things could
go wrong for ARM if these weren't used.
llvm-svn: 131878
2011-05-23 06:46:53 +08:00
|
|
|
m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
|
2010-06-09 00:52:24 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
|
|
|
|
{
|
|
|
|
m_bp_site_sp = bp_site_sp;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
BreakpointLocation::ClearBreakpointSite ()
|
|
|
|
{
|
|
|
|
if (m_bp_site_sp.get())
|
|
|
|
{
|
2010-06-18 09:00:58 +08:00
|
|
|
m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
|
|
|
|
GetID(), m_bp_site_sp);
|
2010-06-09 00:52:24 +08:00
|
|
|
m_bp_site_sp.reset();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
|
|
|
|
{
|
|
|
|
SymbolContext sc;
|
|
|
|
s->Indent();
|
|
|
|
BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
|
|
|
|
|
|
|
|
if (level == lldb::eDescriptionLevelBrief)
|
|
|
|
return;
|
|
|
|
|
|
|
|
s->PutCString(": ");
|
|
|
|
|
|
|
|
if (level == lldb::eDescriptionLevelVerbose)
|
|
|
|
s->IndentMore();
|
|
|
|
|
|
|
|
if (m_address.IsSectionOffset())
|
|
|
|
{
|
|
|
|
m_address.CalculateSymbolContext(&sc);
|
|
|
|
|
|
|
|
if (level == lldb::eDescriptionLevelFull)
|
|
|
|
{
|
|
|
|
s->PutCString("where = ");
|
2010-09-04 01:10:42 +08:00
|
|
|
sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (sc.module_sp)
|
|
|
|
{
|
|
|
|
s->EOL();
|
|
|
|
s->Indent("module = ");
|
|
|
|
sc.module_sp->GetFileSpec().Dump (s);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sc.comp_unit != NULL)
|
|
|
|
{
|
|
|
|
s->EOL();
|
|
|
|
s->Indent("compile unit = ");
|
2010-10-28 06:58:34 +08:00
|
|
|
static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
if (sc.function != NULL)
|
|
|
|
{
|
|
|
|
s->EOL();
|
|
|
|
s->Indent("function = ");
|
|
|
|
s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sc.line_entry.line > 0)
|
|
|
|
{
|
|
|
|
s->EOL();
|
|
|
|
s->Indent("location = ");
|
2010-09-03 05:44:10 +08:00
|
|
|
sc.line_entry.DumpStopContext (s, true);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// If we don't have a comp unit, see if we have a symbol we can print.
|
|
|
|
if (sc.symbol)
|
|
|
|
{
|
|
|
|
s->EOL();
|
|
|
|
s->Indent("symbol = ");
|
|
|
|
s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (level == lldb::eDescriptionLevelVerbose)
|
|
|
|
{
|
|
|
|
s->EOL();
|
|
|
|
s->Indent();
|
|
|
|
}
|
|
|
|
s->Printf ("%saddress = ", (level == lldb::eDescriptionLevelFull && m_address.IsSectionOffset()) ? ", " : "");
|
|
|
|
ExecutionContextScope *exe_scope = NULL;
|
|
|
|
Target *target = &m_owner.GetTarget();
|
|
|
|
if (target)
|
|
|
|
exe_scope = target->GetProcessSP().get();
|
|
|
|
if (exe_scope == NULL)
|
|
|
|
exe_scope = target;
|
|
|
|
|
|
|
|
m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
|
|
|
|
|
|
|
|
if (level == lldb::eDescriptionLevelVerbose)
|
|
|
|
{
|
|
|
|
s->EOL();
|
|
|
|
s->Indent();
|
|
|
|
s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
|
|
|
|
|
|
|
|
s->Indent();
|
|
|
|
s->Printf ("hit count = %-4u\n", GetHitCount());
|
|
|
|
|
|
|
|
if (m_options_ap.get())
|
|
|
|
{
|
2010-06-18 09:00:58 +08:00
|
|
|
s->Indent();
|
|
|
|
m_options_ap->GetDescription (s, level);
|
|
|
|
s->EOL();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
s->IndentLess();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-18 09:00:58 +08:00
|
|
|
s->Printf(", %sresolved, hit count = %u ",
|
2010-06-09 00:52:24 +08:00
|
|
|
(IsResolved() ? "" : "un"),
|
|
|
|
GetHitCount());
|
2010-06-18 09:00:58 +08:00
|
|
|
if (m_options_ap.get())
|
|
|
|
{
|
|
|
|
m_options_ap->GetDescription (s, level);
|
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
BreakpointLocation::Dump(Stream *s) const
|
|
|
|
{
|
|
|
|
if (s == NULL)
|
|
|
|
return;
|
|
|
|
|
2011-12-02 07:28:38 +08:00
|
|
|
s->Printf("BreakpointLocation %u: tid = %4.4llx load addr = 0x%8.8llx state = %s type = %s breakpoint "
|
2010-06-18 09:00:58 +08:00
|
|
|
"hw_index = %i hit_count = %-4u ignore_count = %-4u",
|
2012-01-26 08:08:14 +08:00
|
|
|
GetID(),
|
|
|
|
GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
|
|
|
|
(uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
|
2012-01-31 06:48:10 +08:00
|
|
|
(m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
|
2012-01-26 08:08:14 +08:00
|
|
|
IsHardware() ? "hardware" : "software",
|
|
|
|
GetHardwareIndex(),
|
|
|
|
GetHitCount(),
|
|
|
|
GetOptionsNoCreate()->GetIgnoreCount());
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|