[lldb-dev] Using LLDB C++ API for automated debugging sessions

Jayvee Neumann via lldb-dev lldb-dev at lists.llvm.org
Wed Jun 26 04:58:25 PDT 2019


Dear LLDB developers,

I am currently stuck while using the C++ API of LLDB. I am unable to
correctly launch a process.
The code I have written looks as follows:

int main(int argc, char *argv[]){
LLDBSentry senty;
SBDebugger dbg(SBDebugger::Create());
...
const char *exeFilePath = "./target";
const char *arch = "x86_64";
const char *platform = "";
const char *dependentLibs = "";
SBError error;
SBTarget tgt = dbg.CreateTarget(exeFilePath, arch, platform, dependentLibs,
error);
...
SBListener listen;
SBProcess proc = tgt.Launch(
listen,
nullptr,
nullptr,
nullptr,
"targetout.txt",
nullptr,
"./",
eLaunchFlagExec | eLaunchFlagDebug,
false,
error
);
...
SBThread thread = proc.GetSelectedThread(); // (1)
...
}

The complete code (usr.cpp) is added as an attachment to this email.
Its output is also added as a text file (stdout.txt) to this email.

The problem I have is, that thread.IsValid() returns null after line (1).
Furthermore, the process says, that its state is eStateStopped, when asked
via proc.IsStopped() it answers "false", however.
The debugging target is a simple file that writes a hexadecimal number
every 10us to stdout. I can see that the target is running, because
targetout.txt is growing in size and its content is valid output from
"target".
Can you tell me what my mistake is?

Kind Regards
Jayvee
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20190626/a961cd52/attachment.html>
-------------- next part --------------
#include <SBDebugger.h>
#include <SBTarget.h>
#include <SBFileSpec.h>
#include <SBAttachInfo.h>
#include <SBError.h>
#include <SBProcess.h>
#include <SBStructuredData.h>
#include <SBStream.h>
#include <SBProcess.h>
#include <SBListener.h>
#include <SBThread.h>
#include <SBEvent.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <iomanip>
#include <cstdlib>

#include <time.h>

void wait(void){
	struct timespec req;
	struct timespec rem;
	req.tv_sec    = 1;
	req.tv_nsec   = 0;
	nanosleep(&req,&rem);
}

using namespace lldb;


std::string stateToString(StateType st){
	switch(st){
		case eStateInvalid:     return "Invalid";
		case eStateUnloaded:    return "Unloaded";
		case eStateConnected:   return "Connected";
		case eStateAttaching:   return "Attaching";
		case eStateLaunching:   return "Launching";
		case eStateStopped:     return "Stopped";
		case eStateRunning:     return "Running";
		case eStateStepping:    return "Stepping";
		case eStateCrashed:     return "Crashed";
		case eStateDetached:    return "Detached";
		case eStateExited:      return "Exited";
		case eStateSuspended:   return "Suspended";
		default:                return "unknown";
	}
}

std::string stopReasonToString(StopReason sr){
	switch(sr){
		case eStopReasonInvalid:          return "Invalid";
		case eStopReasonNone:             return "None";
		case eStopReasonTrace:            return "Trace";
		case eStopReasonBreakpoint:       return "Breakpoint";
		case eStopReasonWatchpoint:       return "Watchpoint";
		case eStopReasonSignal:           return "Signal";
		case eStopReasonException:        return "Exception";
		case eStopReasonExec:             return "Exec";
		case eStopReasonPlanComplete:     return "Plan Complete";
		case eStopReasonThreadExiting:    return "Thread Exiting";
		case eStopReasonInstrumentation:  return "Instrumentation";
	}
}

class LLDBSentry {
public:
  LLDBSentry() {
    // Initialize LLDB
    SBDebugger::Initialize();
  }
  ~LLDBSentry() {
    // Terminate LLDB
    SBDebugger::Terminate();
  }
};

int main(int argc, char *argv[]){
	
	LLDBSentry senty;
	SBDebugger dbg(SBDebugger::Create());
	
	if(!dbg.IsValid()){
		std::cerr << "Could not create debugger." << std::endl;
		return EXIT_FAILURE;
	}
	
	std::cout << std::boolalpha;
	
	std::cout << "==== target creation ===================" << std::endl;
	const char *exeFilePath = "./target";
	const char *arch = "x86_64";
	const char *platform = "";
	const char *dependentLibs = "";	
	SBError error;
	SBTarget tgt = dbg.CreateTarget(exeFilePath, arch, platform, dependentLibs, error);
	
	std::cout << "error.Success()             = " << error.Success() << std::endl;
	std::cout << "tgt.IsValid()               = " << tgt.IsValid() << std::endl;
	
	std::cout << "==== process launch ====================" << std::endl;
	SBListener listen;
	SBProcess proc = tgt.Launch(
		listen,
		nullptr,
		nullptr,
		nullptr,
		"targetout.txt",
		nullptr,
		"./",
		eLaunchFlagExec | eLaunchFlagDebug,
		false,
		error
	);
	
	std::cout << "error.Success()             = " << error.Success() << std::endl;
	std::cout << "proc.IsValid()              = " << proc.IsValid() << std::endl;
	std::cout << "proc.GetProcessID()         = " << proc.GetProcessID() << std::endl;
	std::cout << "proc.GetState()             = " << stateToString(proc.GetState()) << std::endl;
	std::cout << "proc.GetNumThreads()        = " << proc.GetNumThreads() << std::endl;
	std::cout << "proc.Continue()             = " << proc.Continue().Success() << std::endl;
	
	SBEvent event;
	std::cout << "listen.GetNextEvent()       = " << listen.GetNextEvent(event) << std::endl;
	
	std::cout << "==== threading =========================" << std::endl;
	
	SBThread thread = proc.GetSelectedThread();
	
	std::cout << "thread.IsValid()            = " << thread.IsValid() << std::endl;
	std::cout << "thread.GetThreadID()        = " << thread.GetThreadID() << std::endl;
	std::cout << "thread.GetName()            = " << (thread.GetName() ? thread.GetName() : "(null)") << std::endl;
	std::cout << "thread.GetStopReason()      = " << stopReasonToString(thread.GetStopReason()) << std::endl;
	std::cout << "thread.IsSuspended()        = " << thread.IsSuspended() << std::endl;
	std::cout << "thread.IsStopped()          = " << thread.IsStopped() << std::endl;
	std::cout << "proc.GetState()             = " << stateToString(proc.GetState()) << std::endl;
	wait();
	return EXIT_SUCCESS;
}
-------------- next part --------------
==== target creation ===================
error.Success()             = true
tgt.IsValid()               = true
==== process launch ====================
error.Success()             = true
proc.IsValid()              = true
proc.GetProcessID()         = 7693
proc.GetState()             = Stopped
proc.GetNumThreads()        = 1
proc.Continue()             = true
listen.GetNextEvent()       = false
==== threading =========================
thread.IsValid()            = false
thread.GetThreadID()        = 7693
thread.GetName()            = (null)
thread.GetStopReason()      = Invalid
thread.IsSuspended()        = false
thread.IsStopped()          = false
proc.GetState()             = Stopped


More information about the lldb-dev mailing list