llvm-project/lldb/source/API/SBSymbol.cpp

219 lines
4.8 KiB
C++
Raw Normal View History

//===-- SBSymbol.cpp --------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/API/SBSymbol.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
SBSymbol::SBSymbol () :
m_opaque_ptr (NULL)
{
}
SBSymbol::SBSymbol (lldb_private::Symbol *lldb_object_ptr) :
m_opaque_ptr (lldb_object_ptr)
{
}
SBSymbol::SBSymbol (const lldb::SBSymbol &rhs) :
m_opaque_ptr (rhs.m_opaque_ptr)
{
}
const SBSymbol &
SBSymbol::operator = (const SBSymbol &rhs)
{
m_opaque_ptr = rhs.m_opaque_ptr;
return *this;
}
SBSymbol::~SBSymbol ()
{
m_opaque_ptr = NULL;
}
void
SBSymbol::SetSymbol (lldb_private::Symbol *lldb_object_ptr)
{
m_opaque_ptr = lldb_object_ptr;
}
bool
SBSymbol::IsValid () const
{
return m_opaque_ptr != NULL;
}
const char *
SBSymbol::GetName() const
{
2010-10-30 12:51:46 +08:00
const char *name = NULL;
if (m_opaque_ptr)
2010-10-30 12:51:46 +08:00
name = m_opaque_ptr->GetMangled().GetName().AsCString();
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
2010-10-30 12:51:46 +08:00
log->Printf ("SBSymbol(%p)::GetName () => \"%s\"", m_opaque_ptr, name ? name : "");
return name;
}
const char *
SBSymbol::GetMangledName () const
{
2010-10-30 12:51:46 +08:00
const char *name = NULL;
if (m_opaque_ptr)
2010-10-30 12:51:46 +08:00
name = m_opaque_ptr->GetMangled().GetMangledName().AsCString();
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
2010-10-30 12:51:46 +08:00
if (log)
log->Printf ("SBSymbol(%p)::GetMangledName () => \"%s\"", m_opaque_ptr, name ? name : "");
return name;
}
bool
SBSymbol::operator == (const SBSymbol &rhs) const
{
return m_opaque_ptr == rhs.m_opaque_ptr;
}
bool
SBSymbol::operator != (const SBSymbol &rhs) const
{
return m_opaque_ptr != rhs.m_opaque_ptr;
}
bool
SBSymbol::GetDescription (SBStream &description)
{
Stream &strm = description.ref();
if (m_opaque_ptr)
{
m_opaque_ptr->GetDescription (&strm,
lldb::eDescriptionLevelFull, NULL);
}
else
strm.PutCString ("No value");
return true;
}
SBInstructionList
SBSymbol::GetInstructions (SBTarget target)
{
SBInstructionList sb_instructions;
if (m_opaque_ptr)
{
Mutex::Locker api_locker;
ExecutionContext exe_ctx;
SBFrame is now threadsafe using some extra tricks. One issue is that stack frames might go away (the object itself, not the actual logical frame) when we are single stepping due to the way we currently sometimes end up flushing frames when stepping in/out/over. They later will come back to life represented by another object yet they have the same StackID. Now when you get a lldb::SBFrame object, it will track the frame it is initialized with until the thread goes away or the StackID no longer exists in the stack for the thread it was created on. It uses a weak_ptr to both the frame and thread and also stores the StackID. These three items allow us to determine when the stack frame object has gone away (the weak_ptr will be NULL) and allows us to find the correct frame again. In our test suite we had such cases where we were just getting lucky when something like this happened: 1 - stop at breakpoint 2 - get first frame in thread where we stopped 3 - run an expression that causes the program to JIT and run code 4 - run more expressions on the frame from step 2 which was very very luckily still around inside a shared pointer, yet, not part of the current thread (a new stack frame object had appeared with the same stack ID and depth). We now avoid all such issues and properly keep up to date, or we start returning errors when the frame doesn't exist and always responds with invalid answers. Also fixed the UserSettingsController (not going to rewrite this just yet) so that it doesn't crash on shutdown. Using weak_ptr's came in real handy to track when the master controller has already gone away and this allowed me to pull out the previous NotifyOwnerIsShuttingDown() patch as it is no longer needed. llvm-svn: 149231
2012-01-30 15:41:31 +08:00
TargetSP target_sp (target.GetSP());
if (target_sp)
{
api_locker.Lock (target_sp->GetAPIMutex());
SBFrame is now threadsafe using some extra tricks. One issue is that stack frames might go away (the object itself, not the actual logical frame) when we are single stepping due to the way we currently sometimes end up flushing frames when stepping in/out/over. They later will come back to life represented by another object yet they have the same StackID. Now when you get a lldb::SBFrame object, it will track the frame it is initialized with until the thread goes away or the StackID no longer exists in the stack for the thread it was created on. It uses a weak_ptr to both the frame and thread and also stores the StackID. These three items allow us to determine when the stack frame object has gone away (the weak_ptr will be NULL) and allows us to find the correct frame again. In our test suite we had such cases where we were just getting lucky when something like this happened: 1 - stop at breakpoint 2 - get first frame in thread where we stopped 3 - run an expression that causes the program to JIT and run code 4 - run more expressions on the frame from step 2 which was very very luckily still around inside a shared pointer, yet, not part of the current thread (a new stack frame object had appeared with the same stack ID and depth). We now avoid all such issues and properly keep up to date, or we start returning errors when the frame doesn't exist and always responds with invalid answers. Also fixed the UserSettingsController (not going to rewrite this just yet) so that it doesn't crash on shutdown. Using weak_ptr's came in real handy to track when the master controller has already gone away and this allowed me to pull out the previous NotifyOwnerIsShuttingDown() patch as it is no longer needed. llvm-svn: 149231
2012-01-30 15:41:31 +08:00
target_sp->CalculateExecutionContext (exe_ctx);
}
if (m_opaque_ptr->ValueIsAddress())
{
ModuleSP module_sp (m_opaque_ptr->GetAddress().GetModule());
if (module_sp)
{
AddressRange symbol_range (m_opaque_ptr->GetAddress(), m_opaque_ptr->GetByteSize());
sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture (),
NULL,
exe_ctx,
symbol_range));
}
}
}
return sb_instructions;
}
lldb_private::Symbol *
SBSymbol::get ()
{
return m_opaque_ptr;
}
void
SBSymbol::reset (lldb_private::Symbol *symbol)
{
m_opaque_ptr = symbol;
}
SBAddress
SBSymbol::GetStartAddress ()
{
SBAddress addr;
if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress())
{
addr.SetAddress (&m_opaque_ptr->GetAddress());
}
return addr;
}
SBAddress
SBSymbol::GetEndAddress ()
{
SBAddress addr;
if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress())
{
lldb::addr_t range_size = m_opaque_ptr->GetByteSize();
if (range_size > 0)
{
addr.SetAddress (&m_opaque_ptr->GetAddress());
addr->Slide (m_opaque_ptr->GetByteSize());
}
}
return addr;
}
uint32_t
SBSymbol::GetPrologueByteSize ()
{
if (m_opaque_ptr)
return m_opaque_ptr->GetPrologueByteSize();
return 0;
}
SymbolType
SBSymbol::GetType ()
{
if (m_opaque_ptr)
return m_opaque_ptr->GetType();
return eSymbolTypeInvalid;
}
bool
SBSymbol::IsExternal()
{
if (m_opaque_ptr)
return m_opaque_ptr->IsExternal();
return false;
}
bool
SBSymbol::IsSynthetic()
{
if (m_opaque_ptr)
return m_opaque_ptr->IsSynthetic();
return false;
}