[lldb-dev] using lldb's backtrace as a library
Greg Clayton
gclayton at apple.com
Tue Mar 4 13:46:20 PST 2014
On Mar 4, 2014, at 1:08 PM, Timothee Cour <thelastmammoth at gmail.com> wrote:
> I'd like to use lldb's backtrace as a library as opposed to using lldb program, so that I can generate good stack traces inside a C/C++/D program without having to spawn a separate process that would call 'lldb -p pid'.
>
> How should I proceed? Or, what is the relevant function call?
This should get you started:
You will link against LLDB.framework on MacOSX, or liblldb.so on unix, or liblldb.dll on windows.
The you would do:
#if defined(__APPLE__)
#include <LLDB/LLDB.h>
#else
#include "lldb/SBDefines.h"
#include "lldb/SBAddress.h"
#include "lldb/SBBlock.h"
#include "lldb/SBBreakpoint.h"
#include "lldb/SBBreakpointLocation.h"
#include "lldb/SBBroadcaster.h"
#include "lldb/SBCommandInterpreter.h"
#include "lldb/SBCommandReturnObject.h"
#include "lldb/SBCommunication.h"
#include "lldb/SBCompileUnit.h"
#include "lldb/SBData.h"
#include "lldb/SBDebugger.h"
#include "lldb/SBDeclaration.h"
#include "lldb/SBError.h"
#include "lldb/SBEvent.h"
#include "lldb/SBFileSpec.h"
#include "lldb/SBFrame.h"
#include "lldb/SBFunction.h"
#include "lldb/SBHostOS.h"
#include "lldb/SBInstruction.h"
#include "lldb/SBInstructionList.h"
#include "lldb/SBLineEntry.h"
#include "lldb/SBListener.h"
#include "lldb/SBModule.h"
#include "lldb/SBProcess.h"
#include "lldb/SBQueue.h"
#include "lldb/SBQueueItem.h"
#include "lldb/SBSourceManager.h"
#include "lldb/SBStream.h"
#include "lldb/SBStringList.h"
#include "lldb/SBSymbol.h"
#include "lldb/SBSymbolContext.h"
#include "lldb/SBTarget.h"
#include "lldb/SBThread.h"
#include "lldb/SBType.h"
#include "lldb/SBValue.h"
#include "lldb/SBValueList.h"
#endif
using namespace lldb;
int main(int argc, const char * argv[])
{
if (argc != 2)
{
printf ("usage: backtrace <pid>\n");
exit(0);
}
SBDebugger::Initialize();
const bool source_init_files = true;
SBDebugger debugger = SBDebugger::Create(source_init_files);
debugger.SetAsync (false); // Set debugger to synchronous mode
const char *filename = NULL; // Fill this in if you know the filename, else leave NULL
const char *target_triple = "x86_64";
const char *platform_name = NULL; // Leave NULL
bool add_dependent_modules = true; //
lldb::SBError error;
lldb::pid_t pid = (int)strtol(argv[1], (char **)NULL, 10);
SBAttachInfo attach_info (pid);
SBTarget target = debugger.CreateTarget (filename, target_triple, platform_name, add_dependent_modules, error);
SBStream stream;
stream.RedirectToFileHandle(stdout, false);
if (target.IsValid())
{
SBProcess process = target.Attach (attach_info, error);
if (process.IsValid())
{
process.GetDescription(stream);
stream.Printf("\n");
uint32_t num_threads = process.GetNumThreads();
for (uint32_t thread_idx=0; thread_idx<num_threads; ++thread_idx)
{
SBThread thread = process.GetThreadAtIndex(thread_idx);
if (thread.IsValid())
{
thread.GetDescription(stream);
stream.Printf("\n");
uint32_t num_frames = thread.GetNumFrames();
for (uint32_t frame_idx=0; frame_idx<num_frames; ++frame_idx)
{
SBFrame frame = thread.GetFrameAtIndex(frame_idx);
frame.GetDescription(stream);
}
}
}
process.Detach();
}
else
{
fprintf(stderr, "error: failed to attach to process: %s\n", error.GetCString());
}
}
else
{
fprintf(stderr, "error: failed to create target: %s\n", error.GetCString());
}
SBDebugger::Terminate();
return 0;
}
More information about the lldb-dev
mailing list