[lldb-dev] How to use the C++ API? No useful documentation?
Paul Peet via lldb-dev
lldb-dev at lists.llvm.org
Thu Mar 3 07:23:57 PST 2016
Hi Pavel,
This is the code:
int main() {
using namespace lldb;
SBDebugger::Initialize();
SBDebugger debugger = SBDebugger::Create(true);
if(!debugger.IsValid()) {
return 1;
}
SBTarget target = debugger.CreateTarget("/home/cynecx/dev/helloWorld/main");
if(!target.IsValid()) {
return 1;
}
SBBreakpoint bp1 = target.BreakpointCreateByLocation(
"/home/cynecx/dev/helloWorld/main.cpp", 7);
if(!bp1.IsValid()) {
return 1;
}
bp1.SetEnabled(true);
const char* args[] = { "/home/cynecx/dev/helloWorld/main", 0 };
const char* env[] = { 0 };
SBLaunchInfo launch_info(args);
launch_info.SetEnvironmentEntries(env, true);
launch_info.SetWorkingDirectory("/home/cynecx/dev/helloWorld");
launch_info.SetLaunchFlags(eLaunchFlagStopAtEntry);
SBError error;
SBProcess process = target.Launch(launch_info, error);
if(!process.IsValid() || !error.Success()) {
return 1;
}
error = process.Continue();
if(!error.Success()) {
return 1;
}
while(true) {
SBEvent event;
SBListener listener = debugger.GetListener();
if(listener.WaitForEvent(6, event)) {
if(!event.IsValid()) {
break;
}
const uint32_t event_type = event.GetType();
if (!SBProcess::EventIsProcessEvent(event)) {
continue;
}
if(event_type == SBProcess::eBroadcastBitStateChanged) {
const StateType state = SBProcess::GetStateFromEvent(event);
switch(state) {
default:
continue;
case eStateStopped: {
// static bool runOnce = false;
//
// if(runOnce == false) {
// sleep(1);
// runOnce = true;
// }
SBThread thread = process.GetThreadAtIndex(0);
SBStream stream;
thread.GetStatus(stream);
event.GetDescription(stream);
std::cout << stream.GetData() << std::endl;
auto threadStopReason = thread.GetStopReason();
if(threadStopReason == eStopReasonBreakpoint) {
uint64_t bpId = thread.GetStopReasonDataAtIndex(0);
if(bpId == static_cast<uint64_t>(bp1.GetID())) {
std::cout << "Stopped at breakpoint" << std::endl;
thread.StepOver();
}
} else if (threadStopReason == eStopReasonPlanComplete) {
std::cout << "Stopped at step" << std::endl;
}
break;
}
}
} else if (SBProcess::eBroadcastBitSTDOUT) {
char buffer[1024];
size_t num_bytes = 0;
do
{
num_bytes = process.GetSTDOUT(buffer, sizeof(buffer));
if (num_bytes > 0)
printf("%*s", (int)num_bytes, buffer);
} while (num_bytes == sizeof(buffer));
}
std::cout << "----------" << std::endl;
} else {
break;
}
}
SBDebugger::Terminate();
return 0;
}
main.cpp:
#include <cstddef>
#include <cstdint>
#include <iostream>
int main() {
std::cout << "Hello World" << std::endl;
int i = 0;
std::cin >> i;
if (i == 1) {
return 1;
}
return 0;
}
So the problem is that I am not getting correct thread information
when receiving an eStateStopped event. It kinda seems that when
"thread.GetStatus(stream);", the thread hasn't stopped yet so I always
getting non-determine thread information.
I found out that on my linux vm, it works properly so I thought it
might be an issue with the kernel and stuff but I kinda found a
workaround by simply putting a sleep(1) before querying the thread
information. As expected it gave me correct thread information, also
the step-over worked properly because the thread plan used correct
line information.
To compare both outputs:
Correct one (with sleep(1)):
* thread #1: tid = 5862, 0x0000000000400953 main`main + 35 at
main.cpp:7, name = 'main', stop reason = breakpoint 1.1
frame #0: 0x0000000000400953 main`main + 35 at main.cpp:7
4
5 int main() {
6
-> 7 std::cout << "Hello World" << std::endl;
8
9 int i = 0;
10 std::cin >> i;
0x7f1dc4000930 Event: broadcaster = 0x55da93268068 (lldb.process),
type = 0x00000001 (state-changed), data = { process = 0x55da93268030
(pid = 5862), state = stopped}
----------
* thread #1: tid = 5862, 0x0000000000400953 main`main + 35 at
main.cpp:7, name = 'main', stop reason = breakpoint 1.1
frame #0: 0x0000000000400953 main`main + 35 at main.cpp:7
4
5 int main() {
6
-> 7 std::cout << "Hello World" << std::endl;
8
9 int i = 0;
10 std::cin >> i;
0x7f1dc4001640 Event: broadcaster = 0x55da93268068 (lldb.process),
type = 0x00000001 (state-changed), data = { process = 0x55da93268030
(pid = 5862), state = stopped}
Stopped at breakpoint
----------
Hello World
----------
* thread #1: tid = 5862, 0x0000000000400978 main`main + 72 at
main.cpp:9, name = 'main', stop reason = step over
frame #0: 0x0000000000400978 main`main + 72 at main.cpp:9
6
7 std::cout << "Hello World" << std::endl;
8
-> 9 int i = 0;
10 std::cin >> i;
11
12 if (i == 1) {
0x7f1dc4003ae0 Event: broadcaster = 0x55da93268068 (lldb.process),
type = 0x00000001 (state-changed), data = { process = 0x55da93268030
(pid = 5862), state = stopped}
Stopped at step
----------
And the one with non-determinism:
* thread #1: tid = 9097, 0x0000000000400830 main`_start, name = 'main'
frame #0: 0x0000000000400830 main`_start
main`_start:
0x400830 <+0>: xorl %ebp, %ebp
0x400832 <+2>: movq %rdx, %r9
0x400835 <+5>: popq %rsi
0x400836 <+6>: movq %rsp, %rdx
0x7fbdd0000930 Event: broadcaster = 0x564549feffa8 (lldb.process),
type = 0x00000001 (state-changed), data = { process = 0x564549feff70
(pid = 9097), state = stopped}
----------
* thread #1: tid = 9097, 0x0000000000400830 main`_start, name =
'main', stop reason = breakpoint 1.1
frame #0: 0x0000000000400830 main`_start
main`_start:
0x400830 <+0>: xorl %ebp, %ebp
0x400832 <+2>: movq %rdx, %r9
0x400835 <+5>: popq %rsi
0x400836 <+6>: movq %rsp, %rdx
0x7fbdd0001640 Event: broadcaster = 0x564549feffa8 (lldb.process),
type = 0x00000001 (state-changed), data = { process = 0x564549feff70
(pid = 9097), state = stopped}
Stopped at breakpoint
----------
Hello World
----------
2016-03-03 14:57 GMT+01:00 Pavel Labath <labath at google.com>:
> Hi Paul,
>
> I haven't followed this discussion from the start, and I am now having
> trouble understanding what is the issue at hand here. Could you just
> briefly repeat what is the problem, and maybe send the code for
> reproducing the problem again? Maybe I'll be able to help...
>
> pl
>
> On 3 March 2016 at 13:04, Paul Peet via lldb-dev
> <lldb-dev at lists.llvm.org> wrote:
>> Sorry to bring this up again, but I am not sure if this is really a
>> linux kernel issue anymore, see the following code:
>>
>> if(event_type == SBProcess::eBroadcastBitStateChanged) {
>> const StateType state = SBProcess::GetStateFromEvent(event);
>>
>> switch(state) {
>> default:
>> continue;
>> case eStateStopped: {
>> static bool runOnce = false;
>> if(runOnce == false) {
>> sleep(1); // sleep a second
>> runOnce = true;
>> }
>>
>> SBThread thread = process.GetThreadAtIndex(0);
>> SBStream stream;
>>
>> As I said before that strangely it worked on the vm with kernel 4.4 so
>> I tried using kernel 4.4 and it still didn't work.
>>
>> Next thing I did was enabling lldb's logging and what I noticed was
>> that when the first thread plan is being made it had wrong instruction
>> information that's probably because the thread was still running. So
>> what I tried was this runOnce with a sleep(1) and the result was as I
>> expected, the thread plan contained the correct instruction
>> information and the following breakpoints and step-overs were
>> correctly made.
>>
>> Any chance that this issue lies deep in lldb? Would the lldb log help
>> to trace back the issue?
>>
>> 2016-02-29 19:58 GMT+01:00 Greg Clayton <gclayton at apple.com>:
>>>
>>>> On Feb 28, 2016, at 2:17 PM, Paul Peet <paulpeet17 at gmail.com> wrote:
>>>>
>>>> Hey,
>>>>
>>>> Just to let you know that I think I made some progress in determine the problem.
>>>> I've basically setup an vm (archlinux, linux 4.4, lldb 3.7.1) and
>>>> tried the code on it. To my surprise it gave me proper output without
>>>> non-determinism. YEY.
>>>> I still don't have any idea why it's not working on my host system. I
>>>> might try testing linux 4.4 like I did on the vm.
>>>>
>>>> Do you have any idea/suspicion why it might not work on my system. (I
>>>> can provide additional information if needed).
>>>
>>> I don't. Maybe some of the linux experts out there might be able to help you. Are are working with top of tree LLDB sources right? You might post the exact linux setup you have in case that might allow people to help you out...
>>>
>>> Greg
>>>
>>>
>> _______________________________________________
>> lldb-dev mailing list
>> lldb-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
More information about the lldb-dev
mailing list