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

1352 lines
36 KiB
C++
Raw Normal View History

//===-- SBDebugger.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/lldb-python.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/lldb-private.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBError.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
#include "lldb/API/SBTarget.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBTypeCategory.h"
#include "lldb/API/SBTypeFormat.h"
#include "lldb/API/SBTypeFilter.h"
#include "lldb/API/SBTypeNameSpecifier.h"
#include "lldb/API/SBTypeSummary.h"
#include "lldb/API/SBTypeSynthetic.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/TargetList.h"
#include "llvm/Support/DynamicLibrary.h"
using namespace lldb;
using namespace lldb_private;
SBInputReader::SBInputReader()
{
}
SBInputReader::~SBInputReader()
{
}
SBError
SBInputReader::Initialize(lldb::SBDebugger& sb_debugger, unsigned long (*)(void*, lldb::SBInputReader*, lldb::InputReaderAction, char const*, unsigned long), void*, lldb::InputReaderGranularity, char const*, char const*, bool)
{
return SBError();
}
void
SBInputReader::SetIsDone(bool)
{
}
bool
SBInputReader::IsActive() const
{
return false;
}
static llvm::sys::DynamicLibrary
LoadPlugin (const lldb::DebuggerSP &debugger_sp, const FileSpec& spec, Error& error)
{
llvm::sys::DynamicLibrary dynlib = llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str());
if (dynlib.isValid())
{
typedef bool (*LLDBCommandPluginInit) (lldb::SBDebugger& debugger);
lldb::SBDebugger debugger_sb(debugger_sp);
// This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) function.
// TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays
LLDBCommandPluginInit init_func = (LLDBCommandPluginInit)dynlib.getAddressOfSymbol("_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
if (init_func)
{
if (init_func(debugger_sb))
return dynlib;
else
error.SetErrorString("plug-in refused to load (lldb::PluginInitialize(lldb::SBDebugger) returned false)");
}
else
{
error.SetErrorString("plug-in is missing the required initialization: lldb::PluginInitialize(lldb::SBDebugger)");
}
}
else
{
if (spec.Exists())
error.SetErrorString("this file does not represent a loadable dylib");
else
error.SetErrorString("no such file");
}
return llvm::sys::DynamicLibrary();
}
void
SBDebugger::Initialize ()
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBDebugger::Initialize ()");
SBCommandInterpreter::InitializeSWIG ();
Debugger::Initialize(LoadPlugin);
}
void
SBDebugger::Terminate ()
{
Debugger::Terminate();
}
void
SBDebugger::Clear ()
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBDebugger(%p)::Clear ()",
static_cast<void*>(m_opaque_sp.get()));
if (m_opaque_sp)
m_opaque_sp->ClearIOHandlers ();
m_opaque_sp.reset();
}
SBDebugger
SBDebugger::Create()
{
return SBDebugger::Create(false, NULL, NULL);
}
SBDebugger
SBDebugger::Create(bool source_init_files)
{
return SBDebugger::Create (source_init_files, NULL, NULL);
}
SBDebugger
SBDebugger::Create(bool source_init_files, lldb::LogOutputCallback callback, void *baton)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBDebugger debugger;
// Currently we have issues if this function is called simultaneously on two different
// threads. The issues mainly revolve around the fact that the lldb_private::FormatManager
// uses global collections and having two threads parsing the .lldbinit files can cause
// mayhem. So to get around this for now we need to use a mutex to prevent bad things
// from happening.
static Mutex g_mutex(Mutex::eMutexTypeRecursive);
Mutex::Locker locker(g_mutex);
debugger.reset(Debugger::CreateInstance(callback, baton));
if (log)
{
SBStream sstr;
debugger.GetDescription (sstr);
log->Printf ("SBDebugger::Create () => SBDebugger(%p): %s",
static_cast<void*>(debugger.m_opaque_sp.get()),
sstr.GetData());
}
SBCommandInterpreter interp = debugger.GetCommandInterpreter();
if (source_init_files)
{
interp.get()->SkipLLDBInitFiles(false);
interp.get()->SkipAppInitFiles (false);
SBCommandReturnObject result;
interp.SourceInitFileInHomeDirectory(result);
}
else
{
interp.get()->SkipLLDBInitFiles(true);
interp.get()->SkipAppInitFiles (true);
}
return debugger;
}
void
SBDebugger::Destroy (SBDebugger &debugger)
{
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
{
SBStream sstr;
debugger.GetDescription (sstr);
log->Printf ("SBDebugger::Destroy () => SBDebugger(%p): %s",
static_cast<void*>(debugger.m_opaque_sp.get()),
sstr.GetData());
}
Debugger::Destroy (debugger.m_opaque_sp);
if (debugger.m_opaque_sp.get() != NULL)
debugger.m_opaque_sp.reset();
}
void
SBDebugger::MemoryPressureDetected ()
{
// Since this function can be call asynchronously, we allow it to be
// non-mandatory. We have seen deadlocks with this function when called
// so we need to safeguard against this until we can determine what is
// causing the deadlocks.
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
const bool mandatory = false;
if (log)
{
log->Printf ("SBDebugger::MemoryPressureDetected (), mandatory = %d", mandatory);
}
ModuleList::RemoveOrphanSharedModules(mandatory);
}
SBDebugger::SBDebugger () :
m_opaque_sp ()
{
}
SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp) :
m_opaque_sp(debugger_sp)
{
}
SBDebugger::SBDebugger(const SBDebugger &rhs) :
m_opaque_sp (rhs.m_opaque_sp)
{
}
SBDebugger &
SBDebugger::operator = (const SBDebugger &rhs)
{
if (this != &rhs)
{
m_opaque_sp = rhs.m_opaque_sp;
}
return *this;
}
SBDebugger::~SBDebugger ()
{
}
bool
SBDebugger::IsValid() const
{
return m_opaque_sp.get() != NULL;
}
void
SBDebugger::SetAsync (bool b)
{
if (m_opaque_sp)
m_opaque_sp->SetAsyncExecution(b);
}
bool
SBDebugger::GetAsync ()
{
if (m_opaque_sp)
return m_opaque_sp->GetAsyncExecution();
else
return false;
}
void
SBDebugger::SkipLLDBInitFiles (bool b)
{
if (m_opaque_sp)
m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles (b);
}
void
SBDebugger::SkipAppInitFiles (bool b)
{
if (m_opaque_sp)
m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles (b);
}
// Shouldn't really be settable after initialization as this could cause lots of problems; don't want users
// trying to switch modes in the middle of a debugging session.
void
SBDebugger::SetInputFileHandle (FILE *fh, bool transfer_ownership)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBDebugger(%p)::SetInputFileHandle (fh=%p, transfer_ownership=%i)",
static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(fh), transfer_ownership);
if (m_opaque_sp)
m_opaque_sp->SetInputFileHandle (fh, transfer_ownership);
}
void
SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBDebugger(%p)::SetOutputFileHandle (fh=%p, transfer_ownership=%i)",
static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(fh), transfer_ownership);
if (m_opaque_sp)
m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership);
}
void
SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBDebugger(%p)::SetErrorFileHandle (fh=%p, transfer_ownership=%i)",
static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(fh), transfer_ownership);
if (m_opaque_sp)
m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership);
}
FILE *
SBDebugger::GetInputFileHandle ()
{
if (m_opaque_sp)
{
StreamFileSP stream_file_sp (m_opaque_sp->GetInputFile());
if (stream_file_sp)
return stream_file_sp->GetFile().GetStream();
}
return NULL;
}
FILE *
SBDebugger::GetOutputFileHandle ()
{
if (m_opaque_sp)
{
StreamFileSP stream_file_sp (m_opaque_sp->GetOutputFile());
if (stream_file_sp)
return stream_file_sp->GetFile().GetStream();
}
return NULL;
}
FILE *
SBDebugger::GetErrorFileHandle ()
{
if (m_opaque_sp)
if (m_opaque_sp)
{
StreamFileSP stream_file_sp (m_opaque_sp->GetErrorFile());
if (stream_file_sp)
return stream_file_sp->GetFile().GetStream();
}
return NULL;
}
void
SBDebugger::SaveInputTerminalState()
{
if (m_opaque_sp)
m_opaque_sp->SaveInputTerminalState();
}
void
SBDebugger::RestoreInputTerminalState()
{
if (m_opaque_sp)
m_opaque_sp->RestoreInputTerminalState();
}
SBCommandInterpreter
SBDebugger::GetCommandInterpreter ()
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBCommandInterpreter sb_interpreter;
if (m_opaque_sp)
sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter());
if (log)
log->Printf ("SBDebugger(%p)::GetCommandInterpreter () => SBCommandInterpreter(%p)",
static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(sb_interpreter.get()));
return sb_interpreter;
}
void
SBDebugger::HandleCommand (const char *command)
{
if (m_opaque_sp)
{
TargetSP target_sp (m_opaque_sp->GetSelectedTarget());
Mutex::Locker api_locker;
if (target_sp)
api_locker.Lock(target_sp->GetAPIMutex());
SBCommandInterpreter sb_interpreter(GetCommandInterpreter ());
SBCommandReturnObject result;
sb_interpreter.HandleCommand (command, result, false);
if (GetErrorFileHandle() != NULL)
result.PutError (GetErrorFileHandle());
if (GetOutputFileHandle() != NULL)
result.PutOutput (GetOutputFileHandle());
if (m_opaque_sp->GetAsyncExecution() == false)
{
SBProcess process(GetCommandInterpreter().GetProcess ());
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
ProcessSP process_sp (process.GetSP());
if (process_sp)
{
EventSP event_sp;
Listener &lldb_listener = m_opaque_sp->GetListener();
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
while (lldb_listener.GetNextEventForBroadcaster (process_sp.get(), event_sp))
{
SBEvent event(event_sp);
HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
}
}
}
}
}
SBListener
SBDebugger::GetListener ()
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBListener sb_listener;
if (m_opaque_sp)
sb_listener.reset(&m_opaque_sp->GetListener(), false);
if (log)
log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)",
static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(sb_listener.get()));
return sb_listener;
}
void
SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *err)
{
if (!process.IsValid())
return;
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 (process.GetTarget().GetSP());
if (!target_sp)
return;
const uint32_t event_type = event.GetType();
char stdio_buffer[1024];
size_t len;
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
Mutex::Locker api_locker (target_sp->GetAPIMutex());
if (event_type & (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged))
{
// Drain stdout when we stop just in case we have any bytes
while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
if (out != NULL)
::fwrite (stdio_buffer, 1, len, out);
}
if (event_type & (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged))
{
// Drain stderr when we stop just in case we have any bytes
while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
if (err != NULL)
::fwrite (stdio_buffer, 1, len, err);
}
if (event_type & Process::eBroadcastBitStateChanged)
{
StateType event_state = SBProcess::GetStateFromEvent (event);
if (event_state == eStateInvalid)
return;
bool is_stopped = StateIsStoppedState (event_state);
if (!is_stopped)
process.ReportEventState (event, out);
}
}
SBSourceManager
SBDebugger::GetSourceManager ()
{
SBSourceManager sb_source_manager (*this);
return sb_source_manager;
}
bool
SBDebugger::GetDefaultArchitecture (char *arch_name, size_t arch_name_len)
{
if (arch_name && arch_name_len)
{
ArchSpec default_arch = Target::GetDefaultArchitecture ();
if (default_arch.IsValid())
{
const std::string &triple_str = default_arch.GetTriple().str();
if (!triple_str.empty())
::snprintf (arch_name, arch_name_len, "%s", triple_str.c_str());
else
::snprintf (arch_name, arch_name_len, "%s", default_arch.GetArchitectureName());
return true;
}
}
if (arch_name && arch_name_len)
arch_name[0] = '\0';
return false;
}
bool
SBDebugger::SetDefaultArchitecture (const char *arch_name)
{
if (arch_name)
{
ArchSpec arch (arch_name);
if (arch.IsValid())
{
Target::SetDefaultArchitecture (arch);
return true;
}
}
return false;
}
ScriptLanguage
SBDebugger::GetScriptingLanguage (const char *script_language_name)
{
return Args::StringToScriptLanguage (script_language_name,
eScriptLanguageDefault,
NULL);
}
const char *
SBDebugger::GetVersionString ()
{
return lldb_private::GetVersion();
}
const char *
SBDebugger::StateAsCString (StateType state)
{
return lldb_private::StateAsCString (state);
}
bool
SBDebugger::StateIsRunningState (StateType state)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
2010-10-30 12:51:46 +08:00
const bool result = lldb_private::StateIsRunningState (state);
2010-10-30 12:51:46 +08:00
if (log)
log->Printf ("SBDebugger::StateIsRunningState (state=%s) => %i",
StateAsCString (state), result);
2010-10-30 12:51:46 +08:00
return result;
}
bool
SBDebugger::StateIsStoppedState (StateType state)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
const bool result = lldb_private::StateIsStoppedState (state, false);
if (log)
2010-10-30 12:51:46 +08:00
log->Printf ("SBDebugger::StateIsStoppedState (state=%s) => %i",
StateAsCString (state), result);
2010-10-30 12:51:46 +08:00
return result;
}
lldb::SBTarget
SBDebugger::CreateTarget (const char *filename,
const char *target_triple,
const char *platform_name,
bool add_dependent_modules,
lldb::SBError& sb_error)
{
SBTarget sb_target;
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;
if (m_opaque_sp)
{
sb_error.Clear();
OptionGroupPlatform platform_options (false);
platform_options.SetPlatformName (platform_name);
sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
filename,
target_triple,
add_dependent_modules,
&platform_options,
target_sp);
if (sb_error.Success())
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
sb_target.SetSP (target_sp);
}
else
{
sb_error.SetErrorString("invalid target");
}
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, platform_name=%s, add_dependent_modules=%u, error=%s) => SBTarget(%p)",
static_cast<void*>(m_opaque_sp.get()), filename,
target_triple, platform_name, add_dependent_modules,
sb_error.GetCString(), static_cast<void*>(target_sp.get()));
return sb_target;
}
SBTarget
SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename,
const char *target_triple)
{
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
SBTarget sb_target;
TargetSP target_sp;
if (m_opaque_sp)
{
const bool add_dependent_modules = true;
Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
filename,
target_triple,
add_dependent_modules,
NULL,
target_sp));
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
sb_target.SetSP (target_sp);
}
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
2010-10-30 12:51:46 +08:00
if (log)
log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple (filename=\"%s\", triple=%s) => SBTarget(%p)",
static_cast<void*>(m_opaque_sp.get()), filename,
target_triple, static_cast<void*>(target_sp.get()));
2010-10-30 12:51:46 +08:00
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
return sb_target;
}
SBTarget
Abtracted all mach-o and ELF out of ArchSpec. This patch is a modified form of Stephen Wilson's idea (thanks for the input Stephen!). What I ended up doing was: - Got rid of ArchSpec::CPU (which was a generic CPU enumeration that mimics the contents of llvm::Triple::ArchType). We now rely upon the llvm::Triple to give us the machine type from llvm::Triple::ArchType. - There is a new ArchSpec::Core definition which further qualifies the CPU core we are dealing with into a single enumeration. If you need support for a new Core and want to debug it in LLDB, it must be added to this list. In the future we can allow for dynamic core registration, but for now it is hard coded. - The ArchSpec can now be initialized with a llvm::Triple or with a C string that represents the triple (it can just be an arch still like "i386"). - The ArchSpec can still initialize itself with a architecture type -- mach-o with cpu type and subtype, or ELF with e_machine + e_flags -- and this will then get translated into the internal llvm::Triple::ArchSpec + ArchSpec::Core. The mach-o cpu type and subtype can be accessed using the getter functions: uint32_t ArchSpec::GetMachOCPUType () const; uint32_t ArchSpec::GetMachOCPUSubType () const; But these functions are just converting out internal llvm::Triple::ArchSpec + ArchSpec::Core back into mach-o. Same goes for ELF. All code has been updated to deal with the changes. This should abstract us until later when the llvm::TargetSpec stuff gets finalized and we can then adopt it. llvm-svn: 126278
2011-02-23 08:35:02 +08:00
SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *arch_cstr)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
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
SBTarget sb_target;
TargetSP target_sp;
if (m_opaque_sp)
{
Error error;
const bool add_dependent_modules = true;
error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
filename,
arch_cstr,
add_dependent_modules,
NULL,
target_sp);
if (error.Success())
{
m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
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
sb_target.SetSP (target_sp);
}
}
if (log)
log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", arch=%s) => SBTarget(%p)",
static_cast<void*>(m_opaque_sp.get()), filename, arch_cstr,
static_cast<void*>(target_sp.get()));
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
return sb_target;
}
SBTarget
SBDebugger::CreateTarget (const char *filename)
{
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
SBTarget sb_target;
TargetSP target_sp;
if (m_opaque_sp)
{
ArchSpec arch = Target::GetDefaultArchitecture ();
Error error;
const bool add_dependent_modules = true;
PlatformSP platform_sp(m_opaque_sp->GetPlatformList().GetSelectedPlatform());
error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
filename,
arch,
add_dependent_modules,
platform_sp,
target_sp);
if (error.Success())
{
m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
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
sb_target.SetSP (target_sp);
}
}
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
2010-10-30 12:51:46 +08:00
if (log)
log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)",
static_cast<void*>(m_opaque_sp.get()), filename,
static_cast<void*>(target_sp.get()));
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
return sb_target;
}
bool
SBDebugger::DeleteTarget (lldb::SBTarget &target)
{
bool result = false;
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
if (m_opaque_sp)
{
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)
{
// No need to lock, the target list is thread safe
result = m_opaque_sp->GetTargetList().DeleteTarget (target_sp);
target_sp->Destroy();
target.Clear();
const bool mandatory = true;
ModuleList::RemoveOrphanSharedModules(mandatory);
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
}
}
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i",
static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(target.m_opaque_sp.get()), result);
return result;
}
SBTarget
SBDebugger::GetTargetAtIndex (uint32_t idx)
{
SBTarget sb_target;
if (m_opaque_sp)
{
// No need to lock, the target list is thread safe
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
sb_target.SetSP (m_opaque_sp->GetTargetList().GetTargetAtIndex (idx));
}
return sb_target;
}
uint32_t
SBDebugger::GetIndexOfTarget (lldb::SBTarget target)
{
lldb::TargetSP target_sp = target.GetSP();
if (!target_sp)
return UINT32_MAX;
if (!m_opaque_sp)
return UINT32_MAX;
return m_opaque_sp->GetTargetList().GetIndexOfTarget (target.GetSP());
}
SBTarget
SBDebugger::FindTargetWithProcessID (lldb::pid_t pid)
{
SBTarget sb_target;
if (m_opaque_sp)
{
// No need to lock, the target list is thread safe
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
sb_target.SetSP (m_opaque_sp->GetTargetList().FindTargetWithProcessID (pid));
}
return sb_target;
}
SBTarget
SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name)
{
SBTarget sb_target;
if (m_opaque_sp && filename && filename[0])
{
// No need to lock, the target list is thread safe
ArchSpec arch (arch_name, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture (FileSpec(filename, false), arch_name ? &arch : NULL));
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
sb_target.SetSP (target_sp);
}
return sb_target;
}
SBTarget
SBDebugger::FindTargetWithLLDBProcess (const ProcessSP &process_sp)
{
SBTarget sb_target;
if (m_opaque_sp)
{
// No need to lock, the target list is thread safe
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
sb_target.SetSP (m_opaque_sp->GetTargetList().FindTargetWithProcess (process_sp.get()));
}
return sb_target;
}
uint32_t
SBDebugger::GetNumTargets ()
{
if (m_opaque_sp)
{
// No need to lock, the target list is thread safe
return m_opaque_sp->GetTargetList().GetNumTargets ();
}
return 0;
}
SBTarget
SBDebugger::GetSelectedTarget ()
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBTarget sb_target;
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;
if (m_opaque_sp)
{
// No need to lock, the target list is thread safe
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 = m_opaque_sp->GetTargetList().GetSelectedTarget ();
sb_target.SetSP (target_sp);
}
if (log)
{
SBStream sstr;
sb_target.GetDescription (sstr, eDescriptionLevelBrief);
log->Printf ("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s",
static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(target_sp.get()), sstr.GetData());
}
return sb_target;
}
void
SBDebugger::SetSelectedTarget (SBTarget &sb_target)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
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 (sb_target.GetSP());
if (m_opaque_sp)
{
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
m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
}
if (log)
{
SBStream sstr;
sb_target.GetDescription (sstr, eDescriptionLevelBrief);
log->Printf ("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s",
static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(target_sp.get()), sstr.GetData());
}
}
SBPlatform
SBDebugger::GetSelectedPlatform()
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBPlatform sb_platform;
DebuggerSP debugger_sp(m_opaque_sp);
if (debugger_sp)
{
sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform());
}
if (log)
log->Printf ("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s",
static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(sb_platform.GetSP().get()),
sb_platform.GetName());
return sb_platform;
}
void
SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform)
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
DebuggerSP debugger_sp(m_opaque_sp);
if (debugger_sp)
{
debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP());
}
if (log)
log->Printf ("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)",
static_cast<void*>(m_opaque_sp.get()),
static_cast<void*>(sb_platform.GetSP().get()),
sb_platform.GetName());
}
void
SBDebugger::DispatchInput (void* baton, const void *data, size_t data_len)
{
DispatchInput (data,data_len);
}
void
SBDebugger::DispatchInput (const void *data, size_t data_len)
{
// Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
//
// if (log)
// log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", size_t=%" PRIu64 ")",
// m_opaque_sp.get(),
// (int) data_len,
// (const char *) data,
// (uint64_t)data_len);
//
// if (m_opaque_sp)
// m_opaque_sp->DispatchInput ((const char *) data, data_len);
}
void
SBDebugger::DispatchInputInterrupt ()
{
if (m_opaque_sp)
m_opaque_sp->DispatchInputInterrupt ();
}
void
SBDebugger::DispatchInputEndOfFile ()
{
if (m_opaque_sp)
m_opaque_sp->DispatchInputEndOfFile ();
}
void
SBDebugger::PushInputReader (SBInputReader &reader)
{
}
void
SBDebugger::RunCommandInterpreter (bool auto_handle_events,
bool spawn_thread)
{
if (m_opaque_sp)
m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(auto_handle_events, spawn_thread);
}
void
SBDebugger::reset (const DebuggerSP &debugger_sp)
{
m_opaque_sp = debugger_sp;
}
Debugger *
SBDebugger::get () const
{
return m_opaque_sp.get();
}
Debugger &
SBDebugger::ref () const
{
assert (m_opaque_sp.get());
return *m_opaque_sp;
}
const lldb::DebuggerSP &
SBDebugger::get_sp () const
{
return m_opaque_sp;
}
SBDebugger
SBDebugger::FindDebuggerWithID (int id)
{
// No need to lock, the debugger list is thread safe
SBDebugger sb_debugger;
DebuggerSP debugger_sp = Debugger::FindDebuggerWithID (id);
if (debugger_sp)
sb_debugger.reset (debugger_sp);
return sb_debugger;
}
const char *
SBDebugger::GetInstanceName()
{
if (m_opaque_sp)
return m_opaque_sp->GetInstanceName().AsCString();
else
return NULL;
}
SBError
SBDebugger::SetInternalVariable (const char *var_name, const char *value, const char *debugger_instance_name)
{
SBError sb_error;
DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName (ConstString(debugger_instance_name)));
Error error;
if (debugger_sp)
{
ExecutionContext exe_ctx (debugger_sp->GetCommandInterpreter().GetExecutionContext());
error = debugger_sp->SetPropertyValue (&exe_ctx,
eVarSetOperationAssign,
var_name,
value);
}
else
{
error.SetErrorStringWithFormat ("invalid debugger instance name '%s'", debugger_instance_name);
}
if (error.Fail())
sb_error.SetError(error);
return sb_error;
}
SBStringList
SBDebugger::GetInternalVariableValue (const char *var_name, const char *debugger_instance_name)
{
SBStringList ret_value;
DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName (ConstString(debugger_instance_name)));
Error error;
if (debugger_sp)
{
ExecutionContext exe_ctx (debugger_sp->GetCommandInterpreter().GetExecutionContext());
lldb::OptionValueSP value_sp (debugger_sp->GetPropertyValue (&exe_ctx,
var_name,
false,
error));
if (value_sp)
{
StreamString value_strm;
value_sp->DumpValue (&exe_ctx, value_strm, OptionValue::eDumpOptionValue);
const std::string &value_str = value_strm.GetString();
if (!value_str.empty())
{
StringList string_list;
string_list.SplitIntoLines(value_str);
return SBStringList(&string_list);
}
}
}
return SBStringList();
}
uint32_t
SBDebugger::GetTerminalWidth () const
{
if (m_opaque_sp)
return m_opaque_sp->GetTerminalWidth ();
return 0;
}
void
SBDebugger::SetTerminalWidth (uint32_t term_width)
{
if (m_opaque_sp)
m_opaque_sp->SetTerminalWidth (term_width);
}
const char *
SBDebugger::GetPrompt() const
{
Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBDebugger(%p)::GetPrompt () => \"%s\"",
static_cast<void*>(m_opaque_sp.get()),
(m_opaque_sp ? m_opaque_sp->GetPrompt() : ""));
if (m_opaque_sp)
return m_opaque_sp->GetPrompt ();
return 0;
}
void
SBDebugger::SetPrompt (const char *prompt)
{
if (m_opaque_sp)
m_opaque_sp->SetPrompt (prompt);
}
ScriptLanguage
SBDebugger::GetScriptLanguage() const
{
if (m_opaque_sp)
return m_opaque_sp->GetScriptLanguage ();
return eScriptLanguageNone;
}
void
SBDebugger::SetScriptLanguage (ScriptLanguage script_lang)
{
if (m_opaque_sp)
{
m_opaque_sp->SetScriptLanguage (script_lang);
}
}
bool
SBDebugger::SetUseExternalEditor (bool value)
{
if (m_opaque_sp)
return m_opaque_sp->SetUseExternalEditor (value);
return false;
}
bool
SBDebugger::GetUseExternalEditor ()
{
if (m_opaque_sp)
return m_opaque_sp->GetUseExternalEditor ();
return false;
}
bool
SBDebugger::SetUseColor (bool value)
{
if (m_opaque_sp)
return m_opaque_sp->SetUseColor (value);
return false;
}
bool
SBDebugger::GetUseColor () const
{
if (m_opaque_sp)
return m_opaque_sp->GetUseColor ();
return false;
}
bool
SBDebugger::GetDescription (SBStream &description)
{
Stream &strm = description.ref();
if (m_opaque_sp)
{
const char *name = m_opaque_sp->GetInstanceName().AsCString();
user_id_t id = m_opaque_sp->GetID();
strm.Printf ("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id);
}
else
strm.PutCString ("No value");
return true;
}
user_id_t
SBDebugger::GetID()
{
if (m_opaque_sp)
return m_opaque_sp->GetID();
return LLDB_INVALID_UID;
}
SBError
SBDebugger::SetCurrentPlatform (const char *platform_name)
{
SBError sb_error;
if (m_opaque_sp)
{
PlatformSP platform_sp (Platform::Create (platform_name, sb_error.ref()));
if (platform_sp)
{
bool make_selected = true;
m_opaque_sp->GetPlatformList().Append (platform_sp, make_selected);
}
}
return sb_error;
}
bool
SBDebugger::SetCurrentPlatformSDKRoot (const char *sysroot)
{
if (m_opaque_sp)
{
PlatformSP platform_sp (m_opaque_sp->GetPlatformList().GetSelectedPlatform());
if (platform_sp)
{
platform_sp->SetSDKRootDirectory (ConstString (sysroot));
return true;
}
}
return false;
}
bool
SBDebugger::GetCloseInputOnEOF () const
{
if (m_opaque_sp)
return m_opaque_sp->GetCloseInputOnEOF ();
return false;
}
void
SBDebugger::SetCloseInputOnEOF (bool b)
{
if (m_opaque_sp)
m_opaque_sp->SetCloseInputOnEOF (b);
}
SBTypeCategory
SBDebugger::GetCategory (const char* category_name)
{
if (!category_name || *category_name == 0)
return SBTypeCategory();
TypeCategoryImplSP category_sp;
if (DataVisualization::Categories::GetCategory(ConstString(category_name), category_sp, false))
return SBTypeCategory(category_sp);
else
return SBTypeCategory();
}
SBTypeCategory
SBDebugger::CreateCategory (const char* category_name)
{
if (!category_name || *category_name == 0)
return SBTypeCategory();
TypeCategoryImplSP category_sp;
if (DataVisualization::Categories::GetCategory(ConstString(category_name), category_sp, true))
return SBTypeCategory(category_sp);
else
return SBTypeCategory();
}
bool
SBDebugger::DeleteCategory (const char* category_name)
{
if (!category_name || *category_name == 0)
return false;
return DataVisualization::Categories::Delete(ConstString(category_name));
}
uint32_t
SBDebugger::GetNumCategories()
{
return DataVisualization::Categories::GetCount();
}
SBTypeCategory
SBDebugger::GetCategoryAtIndex (uint32_t index)
{
return SBTypeCategory(DataVisualization::Categories::GetCategoryAtIndex(index));
}
SBTypeCategory
SBDebugger::GetDefaultCategory()
{
return GetCategory("default");
}
SBTypeFormat
SBDebugger::GetFormatForType (SBTypeNameSpecifier type_name)
{
SBTypeCategory default_category_sb = GetDefaultCategory();
if (default_category_sb.GetEnabled())
return default_category_sb.GetFormatForType(type_name);
return SBTypeFormat();
}
#ifndef LLDB_DISABLE_PYTHON
SBTypeSummary
SBDebugger::GetSummaryForType (SBTypeNameSpecifier type_name)
{
if (type_name.IsValid() == false)
return SBTypeSummary();
return SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP()));
}
#endif // LLDB_DISABLE_PYTHON
SBTypeFilter
SBDebugger::GetFilterForType (SBTypeNameSpecifier type_name)
{
if (type_name.IsValid() == false)
return SBTypeFilter();
return SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP()));
}
#ifndef LLDB_DISABLE_PYTHON
SBTypeSynthetic
SBDebugger::GetSyntheticForType (SBTypeNameSpecifier type_name)
{
if (type_name.IsValid() == false)
return SBTypeSynthetic();
return SBTypeSynthetic(DataVisualization::GetSyntheticForType(type_name.GetSP()));
}
#endif // LLDB_DISABLE_PYTHON
bool
SBDebugger::EnableLog (const char *channel, const char **categories)
{
if (m_opaque_sp)
{
uint32_t log_options = LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
StreamString errors;
return m_opaque_sp->EnableLog (channel, categories, NULL, log_options, errors);
}
else
return false;
}
void
SBDebugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
{
if (m_opaque_sp)
{
return m_opaque_sp->SetLoggingCallback (log_callback, baton);
}
}