[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