[lldb-dev] How to use the C++ API? No useful documentation?
Hello, I am currently working on an IDE for C++ and I would like to integrate lldb as a debugger using the C++ API but it has been difficult for me to understand the architecture because there is no documentation available (except doxygen which isn't helpful at all). I am at the point understanding the Event system? How are Events created? How can I use SBListener and SBBroadcaster? (What's the function of SBBroadvaster). My current code looks something like this: SBListener listener; SBProcess process = target.Launch(listener, args, env, nullptr, nullptr, nullptr, "/home/cynecx/dev/helloWorld", 0, true, error); process.Continue(); StateType state = process.GetState(); // is stopped SBEvent event; while(true) { if(listener.WaitForEvent(0x, event)) { // This branch is never hit SBStream stream; event.GetDescription(stream); std::cout << stream.GetData() << std::endl; } else { break; } } It would help developers (IDE) a lot if there might be some tutorials/documentation on how to use the API. Regards, Paul ___ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] How to use the C++ API? No useful documentation?
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(bp1.GetID())) > { > std::cout << "Stopped at breakpoint" << > std::endl; > thread.StepOver(); > } > } > else if (threadStopReason == > eStopReasonPlanComplete) > { > std::cout << "Stopped at step" << std::endl; > } > } > break; > } > } > break; > case SBProcess::eBroadcastBitSTDOUT: > { > char buffer[1024]; > size_t num_bytes = 0; > do > { > num_bytes = process.GetSTDOUT(buffer, sizeof(buffer)); > // Print exactly num_bytes bytes of the string data > in buffer > if (num_bytes > 0) > printf("%*s", (int)num_bytes, buffer); > } while (num_bytes == sizeof(buffer); > } > break; > } > } > } > > Your main issue was you were grabbing threads even when you weren't stopped, > possibly when you were getting process STDOUT... > > The main differences in the code above are: > 1 - use SBLaunchInfo to launch > 1 - Only try to grab stuff from the process and threads when you are stopped > (only do process.GetThreadAtIndex(...) when you are stopped, not for every > event. What would process return if the process is running for > process.GetThreadAtIndex(0)? Sometimes an invalid thread, sometimes a valid > thread that might be in the middle of a step. When you are stopped, you are > guaranteed to get good results. So make sure you are stopped before you ask > for threads, frames, variables, etc... > 2 - Make sure the event is a process event with > SBProcess::EventIsProcessEvent() as you might get other events if you use the > debugger's listener (target events, thread events, etc) > 3 - Switch off of the event type so you know what kind of event you are > getting. > > Let me know if this fixes things. > > Greg Clayton > > >> On Feb 23, 2016, at 7:10 PM, paulpee...@gmail.com wrote: >> >> >> Thank you very much for that detailed description on explaining the 'basics'. >> >> I got it working so far but there is a small issue with the code I am >> currently running. When the main loop (there is only one) receives a >> breakpoint event and I am trying to get the thread description (After the >> breakpoint I issue the thread.StepOver command to the next line of code), >> the result is not 'deterministic' in terms of it is always showing me >> different current instruction location. Sometimes it's still on the same >> breakpoint line and sometimes it's on the proper next line. How is it that >> the thread is still changing even if the stopped state event got hit? >> >> The code: >> http://pastebin.com/0arNea9m >> >> Sorry about pastebin, I am sending this from my phone and apparently it >> discards the code style while copy and paste. >> >>> On 23 Feb 2016, at 23:40, Greg Clayton wrote: >>> >>> I need to spend some time writing this up, but until then here is some info. >>> >>> We created a python script that uses the LLDB public API to grab async >>> events so people can see how to do things: >>> >>> svn cat >>> http://llvm.org/svn/llvm-project/lldb/trunk/examples/python/process_events.py >>> >>> If you look in here you will see the correct way to do things. >>> >>> I will answer you questions inlined into your email below and then add some >>> extra tips at the end: >>> >>>> On Feb 20, 2016, at 3:04 PM, Paul Peet via lldb-dev >>>> wrote: >>>> >>>> Hello, >>>> >>>&
Re: [lldb-dev] How to use the C++ API? No useful documentation?
>>{ >>>if(!event.IsValid()) >>>break; >>> >>>const uint32_t event_type = event.GetType(); >>> >>>if (SBProcess::EventIsProcessEvent (event)) >>>{ >>>switch (event_type) >>>{ >>>case SBProcess::eBroadcastBitStateChanged: >>>{ >>>const StateType state = >>> SBProcess.GetStateFromEvent(event); >>>switch (state) >>>{ >>>case eStateStopped: >>>{ >>>const uint32_t num_threads = >>> process.GetNumThreads(); >>>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(bp1.GetID())) >>>{ >>>std::cout << "Stopped at breakpoint" << >>> std::endl; >>>thread.StepOver(); >>>} >>>} >>>else if (threadStopReason == >>> eStopReasonPlanComplete) >>>{ >>>std::cout << "Stopped at step" << std::endl; >>>} >>>} >>>break; >>>} >>>} >>>break; >>>case SBProcess::eBroadcastBitSTDOUT: >>>{ >>>char buffer[1024]; >>>size_t num_bytes = 0; >>>do >>>{ >>>num_bytes = process.GetSTDOUT(buffer, >>> sizeof(buffer)); >>>// Print exactly num_bytes bytes of the string data >>> in buffer >>>if (num_bytes > 0) >>>printf("%*s", (int)num_bytes, buffer); >>>} while (num_bytes == sizeof(buffer); >>>} >>>break; >>>} >>>} >>> } >>> >>> Your main issue was you were grabbing threads even when you weren't >>> stopped, possibly when you were getting process STDOUT... >>> >>> The main differences in the code above are: >>> 1 - use SBLaunchInfo to launch >>> 1 - Only try to grab stuff from the process and threads when you are >>> stopped (only do process.GetThreadAtIndex(...) when you are stopped, not >>> for every event. What would process return if the process is running for >>> process.GetThreadAtIndex(0)? Sometimes an invalid thread, sometimes a valid >>> thread that might be in the middle of a step. When you are stopped, you are >>> guaranteed to get good results. So make sure you are stopped before you ask >>> for threads, frames, variables, etc... >>> 2 - Make sure the event is a process event with >>> SBProcess::EventIsProcessEvent() as you might get other events if you use >>> the debugger's listener (target events, thread events, etc) >>> 3 - Switch off of the event type so you know what kind of event you are >>> getting. >>> >>> Let me know if this fixes things. >>> >>> Greg Clayton >>> >>> >>>> On Feb 23, 2016, at 7:10 PM, paulpee...@gmail.com wrote: >>>> >>>> >>>> Thank you very much for that detailed description on explaining the >>>> 'basics'. >>>> >>>> I got it working so far but there is a small issue with the code I am >>>> currently running. When the main loop (there is only one) receives a >>>> breakpoint event and I
Re: [lldb-dev] How to use the C++ API? No useful documentation?
n`_start >>> main`_start: >>>0x400830 <+0>: xorl %ebp, %ebp >>>0x400832 <+2>: movq %rdx, %r9 >>>0x400835 <+5>: popq %rsi >>>0x400836 <+6>: movq %rsp, %rdx >>> 0x7ffaac001640 Event: broadcaster = 0xcdefa8 (lldb.process), type = >>> 0x0001 (state-changed), data = { process = 0xcdef70 (pid = 2535), >>> state = stopped} >>> Stopped at breakpoint >>> -- >>> Hello World >>> -- >>> >>> It is basically missing the "Stepped at step" part which means lldb >>> isn't emitting the PlanCompleteEvent. >>> >>> Is it a problem on my system? (Linux?). >>> >>> 2016-02-24 19:49 GMT+01:00 Greg Clayton : >>>> Here is the fixed code: >>>> >>>> SBListener listener = debugger.GetListener(); >>>> >>>> SBLaunchInfo launch_info(args); >>>> launch_info.SetEnvironmentEntries(env, true); >>>> launch_info.SetWorkingDirectory("/home/dev/helloWorld"); >>>> >>>> SBProcess process = target.Launch(launch_info, error); >>>> >>>> process.GetBroadcaster().AddListener(listener, >>>> SBProcess::eBroadcastBitStateChanged | SBProcess::eBroadcastBitSTDOUT); >>>> >>>> while(true) >>>> { >>>>SBEvent event; >>>> >>>>if(listener.WaitForEvent(6, event)) >>>>{ >>>>if(!event.IsValid()) >>>>break; >>>> >>>>const uint32_t event_type = event.GetType(); >>>> >>>>if (SBProcess::EventIsProcessEvent (event)) >>>>{ >>>>switch (event_type) >>>>{ >>>>case SBProcess::eBroadcastBitStateChanged: >>>>{ >>>>const StateType state = >>>> SBProcess.GetStateFromEvent(event); >>>>switch (state) >>>>{ >>>>case eStateStopped: >>>>{ >>>>const uint32_t num_threads = >>>> process.GetNumThreads(); >>>>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(bp1.GetID())) >>>>{ >>>>std::cout << "Stopped at breakpoint" << >>>> std::endl; >>>>thread.StepOver(); >>>>} >>>>} >>>>else if (threadStopReason == >>>> eStopReasonPlanComplete) >>>>{ >>>>std::cout << "Stopped at step" << std::endl; >>>>} >>>>} >>>>break; >>>>} >>>>} >>>>break; >>>>case SBProcess::eBroadcastBitSTDOUT: >>>>{ >>>>char buffer[1024]; >>>>size_t num_bytes = 0; >>>>do >>>>{ >>>>num_bytes = process.GetSTDOUT(buffer, >>>> sizeof(buffer)); >>>>// Print exactly num_bytes bytes of the string data >>>> in buffer >>>> if (num_bytes > 0) >>>>printf("%*s", (int)num_bytes, buffer); >>>>} while (num_bytes == sizeof(buffer); >>&g
Re: [lldb-dev] How to use the C++ API? No useful documentation?
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 : > >> On Feb 28, 2016, at 2:17 PM, Paul Peet 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@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] How to use the C++ API? No useful documentation?
eakpoint -- Hello World -- * thread #1: tid = 5862, 0x00400978 main`main + 72 at main.cpp:9, name = 'main', stop reason = step over frame #0: 0x00400978 main`main + 72 at main.cpp:9 6 7std::cout << "Hello World" << std::endl; 8 -> 9int i = 0; 10std::cin >> i; 11 12if (i == 1) { 0x7f1dc4003ae0 Event: broadcaster = 0x55da93268068 (lldb.process), type = 0x0001 (state-changed), data = { process = 0x55da93268030 (pid = 5862), state = stopped} Stopped at step -- And the one with non-determinism: * thread #1: tid = 9097, 0x00400830 main`_start, name = 'main' frame #0: 0x00400830 main`_start main`_start: 0x400830 <+0>: xorl %ebp, %ebp 0x400832 <+2>: movq %rdx, %r9 0x400835 <+5>: popq %rsi 0x400836 <+6>: movq %rsp, %rdx 0x7fbdd930 Event: broadcaster = 0x564549feffa8 (lldb.process), type = 0x0001 (state-changed), data = { process = 0x564549feff70 (pid = 9097), state = stopped} -- * thread #1: tid = 9097, 0x00400830 main`_start, name = 'main', stop reason = breakpoint 1.1 frame #0: 0x00400830 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 = 0x0001 (state-changed), data = { process = 0x564549feff70 (pid = 9097), state = stopped} Stopped at breakpoint -- Hello World -- 2016-03-03 14:57 GMT+01:00 Pavel Labath : > 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 > 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 : >>> >>>> On Feb 28, 2016, at 2:17 PM, Paul Peet 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@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev ___ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] How to use the C++ API? No useful documentation?
t;> >>> if(bpId == static_cast(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 >>> #include >>> #include >>> >>> 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, 0x00400953 main`main + 35 at >>> main.cpp:7, name = 'main', stop reason = breakpoint 1.1 >>> frame #0: 0x00400953 main`main + 35 at main.cpp:7 >>>4 >>>5 int main() { >>>6 >>> -> 7std::cout << "Hello World" << std::endl; >>>8 >>>9int i = 0; >>>10std::cin >> i; >>> 0x7f1dc4000930 Event: broadcaster = 0x55da93268068 (lldb.process), >>> type = 0x0001 (state-changed), data = { process = 0x55da93268030 >>> (pid = 5862), state = stopped} >>> -- >>> * thread #1: tid = 5862, 0x00400953 main`main + 35 at >>> main.cpp:7, name = 'main', stop reason = breakpoint 1.1 >>> frame #0: 0x00400953 main`main + 35 at main.cpp:7 >>>4 >>>5 int main() { >>>6 >>> -> 7std::cout << "Hello World" << std::endl; >>>8 >>>9int i = 0; >>>10std::cin >> i; >>> 0x7f1dc4001640 Event: broadcaster = 0x55da93268068 (lldb.process), >>> type = 0x0001 (state-changed), data = { process = 0x55da93268030 >>> (pid = 5862), state = stopped} >>> Stopped at breakpoint >>> -- >>> Hello World >>> ------ >>> * thread #1: tid = 5862, 0x00400978 main`main + 72 at >>> main.cpp:9, name = 'main', stop reason = step over >>> frame #0: 0x00400978 main`main + 72 at main.cpp:9 >>>6 >>>7std::cout << "Hello World" << std::endl; >>>8 >>> -> 9int i = 0; >>>10std::cin >> i; >>>11 >>>12if (i == 1) { >>> 0x7f1dc4003ae0 Event: broadcaster = 0x55da93268068 (lldb.process), >>> type = 0x0001 (state-changed), data = { process = 0x55da93268030 >>> (pid = 5862), state = stopped} >>> Stopped at step >>> -- >>> >>> And the one with non-determinism: >>> >>> * thread #1: tid = 9097,
[lldb-dev] SBListener not using a shared_ptr internally?
Hey, I am currently working on lldb bindings for javascript (v8) but it seems that the API is giving me some troubles. What I am doing is to basically wrap SB* objects into V8 objects, and since SB objects contain a shared_ptr into an internal class I think I can simply copy construct them. To return a wrapped SB object by some Javascript function, I am simply copy constructing the SB object into the wrapper object which is dynamically allocated and when the Javascript object is garbage collected it will also destroy the SBObject (And also the shared_ptr, So it should be save I guess?). Okay, so far so good but I detected some inconsistency when trying to wrap SBListener. The deal was to make SBListener::WaitForEvent non-blocking, to do that I am creating a new thread which calls WaitForEvents, when it returns and the event is valid, the callbacks given from the Javascript code is called. There is a catch when doing this. I have to track the threads which belong to a specific SBListener. But there is not actually easy way to do this because SB objects are just simply shared_ptr. I noticed the GetSP function which returns the shared_ptr of an SBListener, this would be a way to solve this issue as I could use a map which maps the internal SBListener pointer to a Class object which manages the thread and stuff (SBListenerWorker). // etc. mutex, ... static std::unordered_map ListenerWorkers; GetSP is protected so I had to create a new derived class: class SBListener_Internal : public lldb::SBListener { public: SBListener_Internal() = default; SBListener_Internal(const lldb::SBListener& listener) : lldb::SBListener{listener} { } ~SBListener_Internal() = default; void* GetInternalPtr() { return reinterpret_cast(GetSP().get()); } }; I had some worried about if the SBListener object could be destroyed at some point and the internal pointer would still be in the "ListenerWorkers" map so to avoid that I copied the the SBListener object into the class which manages the thread and stuff (SBListenerWorker), that means that the reference counter should be still > 0 when all other shared_ptrs are destroyed. Now to the actual problem, it turns out that GetInternalPtr() actually returns nullptr and instead uses m_opaque_ptr for calling internal functions. This means that the SBListener object isn't actually using a shared_ptr internally, which brings another question up if it is save to use the SBListener across thread? What happens if the SBListener gets destroyed. ___ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] SBListener not using a shared_ptr internally?
I am currently using the package from Arch Linux's repository, it's 3.7.1. So I guess this "patch" will be in llvm/lldb 3.8.1? 2016-03-25 22:42 GMT+01:00 Jim Ingham : > What version of the lldb sources are you working with? I changed the > SBListener over to using only the ListenerSP internally > in r262863. > > Jim > >> On Mar 25, 2016, at 1:03 PM, Paul Peet via lldb-dev >> wrote: >> >> Hey, >> >> I am currently working on lldb bindings for javascript (v8) but it >> seems that the API is giving me some troubles. >> >> What I am doing is to basically wrap SB* objects into V8 objects, and >> since SB objects contain a shared_ptr into an internal class I think I >> can simply copy construct them. >> >> To return a wrapped SB object by some Javascript function, I am simply >> copy constructing the SB object into the wrapper object which is >> dynamically allocated and when the Javascript object is garbage >> collected it will also destroy the SBObject (And also the shared_ptr, >> So it should be save I guess?). >> >> Okay, so far so good but I detected some inconsistency when trying to >> wrap SBListener. The deal was to make SBListener::WaitForEvent >> non-blocking, to do that I am creating a new thread which calls >> WaitForEvents, when it returns and the event is valid, the callbacks >> given from the Javascript code is called. >> >> There is a catch when doing this. I have to track the threads which >> belong to a specific SBListener. But there is not actually easy way to >> do this because SB objects are just simply shared_ptr. I noticed the >> GetSP function which returns the shared_ptr of an SBListener, this >> would be a way to solve this issue as I could use a map which maps the >> internal SBListener pointer to a Class object which manages the thread >> and stuff (SBListenerWorker). >> >> // etc. mutex, ... >> static std::unordered_map ListenerWorkers; >> >> GetSP is protected so I had to create a new derived class: >> >> class SBListener_Internal : public lldb::SBListener { >> public: >> SBListener_Internal() = default; >> SBListener_Internal(const lldb::SBListener& listener) >> : lldb::SBListener{listener} { >> } >> ~SBListener_Internal() = default; >> >> void* GetInternalPtr() { >>return reinterpret_cast(GetSP().get()); >> } >> }; >> >> I had some worried about if the SBListener object could be destroyed >> at some point and the internal pointer would still be in the >> "ListenerWorkers" map so >> to avoid that I copied the the SBListener object into the class which >> manages the thread and stuff (SBListenerWorker), that means that the >> reference counter should be still > 0 when all other shared_ptrs are >> destroyed. >> >> Now to the actual problem, it turns out that GetInternalPtr() actually >> returns nullptr and instead uses m_opaque_ptr for calling internal >> functions. >> This means that the SBListener object isn't actually using a >> shared_ptr internally, which brings another question up if it is save >> to use the SBListener across thread? What happens if the SBListener >> gets destroyed. >> ___ >> lldb-dev mailing list >> lldb-dev@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev > ___ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] SBListener not using a shared_ptr internally?
I am coding bindings for node.js which is basically V8 with an event loop (libuv). So by the nature of nodejs, having "blocking" could stop the whole event-loop, that's why I am trying to make WaitForEvent non-blocking. I am not using swig to do the port. It's more like directly using the V8 api which surprisingly isn't that complicated. 2016-03-25 22:48 GMT+01:00 Greg Clayton : > One question is why are you trying to make SBListener::WaitForEvent > non-blocking? Seems like an implementation that changes the behavior of the > API is going to make the port less useful. Can you go into some detail as to > why you are trying to do this? > > Are you using swig to do the javascript port? > > Greg > >> On Mar 25, 2016, at 1:03 PM, Paul Peet via lldb-dev >> wrote: >> >> Hey, >> >> I am currently working on lldb bindings for javascript (v8) but it >> seems that the API is giving me some troubles. >> >> What I am doing is to basically wrap SB* objects into V8 objects, and >> since SB objects contain a shared_ptr into an internal class I think I >> can simply copy construct them. >> >> To return a wrapped SB object by some Javascript function, I am simply >> copy constructing the SB object into the wrapper object which is >> dynamically allocated and when the Javascript object is garbage >> collected it will also destroy the SBObject (And also the shared_ptr, >> So it should be save I guess?). >> >> Okay, so far so good but I detected some inconsistency when trying to >> wrap SBListener. The deal was to make SBListener::WaitForEvent >> non-blocking, to do that I am creating a new thread which calls >> WaitForEvents, when it returns and the event is valid, the callbacks >> given from the Javascript code is called. >> >> There is a catch when doing this. I have to track the threads which >> belong to a specific SBListener. But there is not actually easy way to >> do this because SB objects are just simply shared_ptr. I noticed the >> GetSP function which returns the shared_ptr of an SBListener, this >> would be a way to solve this issue as I could use a map which maps the >> internal SBListener pointer to a Class object which manages the thread >> and stuff (SBListenerWorker). >> >> // etc. mutex, ... >> static std::unordered_map ListenerWorkers; >> >> GetSP is protected so I had to create a new derived class: >> >> class SBListener_Internal : public lldb::SBListener { >> public: >> SBListener_Internal() = default; >> SBListener_Internal(const lldb::SBListener& listener) >> : lldb::SBListener{listener} { >> } >> ~SBListener_Internal() = default; >> >> void* GetInternalPtr() { >>return reinterpret_cast(GetSP().get()); >> } >> }; >> >> I had some worried about if the SBListener object could be destroyed >> at some point and the internal pointer would still be in the >> "ListenerWorkers" map so >> to avoid that I copied the the SBListener object into the class which >> manages the thread and stuff (SBListenerWorker), that means that the >> reference counter should be still > 0 when all other shared_ptrs are >> destroyed. >> >> Now to the actual problem, it turns out that GetInternalPtr() actually >> returns nullptr and instead uses m_opaque_ptr for calling internal >> functions. >> This means that the SBListener object isn't actually using a >> shared_ptr internally, which brings another question up if it is save >> to use the SBListener across thread? What happens if the SBListener >> gets destroyed. >> ___ >> lldb-dev mailing list >> lldb-dev@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev > ___ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
Re: [lldb-dev] SBListener not using a shared_ptr internally? (Update: Segfault after r262863)
Hey again, I've noticing segfaults after r262863 (dc5ef2da510f3adba99cd8b2fe18c2e6d417227d). Could you try reproducing this bug with this code please? int main() { using namespace lldb; SBDebugger::Initialize(); SBDebugger debugger = SBDebugger::Create(true); if(!debugger.IsValid()) { return 1; } SBTarget target = debugger.CreateTarget("/home/dev/helloWorld/main"); if(!target.IsValid()) { return 1; } const char* args[] = { "/home/dev/helloWorld/main", 0 }; const char* env[] = { 0 }; SBLaunchInfo launch_info(args); launch_info.SetEnvironmentEntries(env, true); launch_info.SetWorkingDirectory("/home/dev/helloWorld"); launch_info.SetLaunchFlags(eLaunchFlagStopAtEntry); SBError error; SBProcess process = target.Launch(launch_info, error); return 0; } I tried to build lldb with and without the above commit and it turns out that the revision is causing the segfault when simply running that code (When it's exiting). This is the backtrace: #0 0x55b03b00 in ?? () #1 0x771be1aa in lldb_private::Broadcaster::BroadcasterImpl::RestoreBroadcaster() () from /usr/lib/liblldb.so.3.8.0 #2 0x7748b674 in lldb_private::process_gdb_remote::GDBRemoteCommunicationClient::SendPacketAndWaitForResponse(char const*, unsigned long, StringExtractorGDBRemote&, bool) () from /usr/lib/liblldb.so.3.8.0 #3 0x7748e89d in lldb_private::process_gdb_remote::GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(lldb_private::process_gdb_remote::GDBStoppointType, bool, unsigned long, unsigned int) () from /usr/lib/liblldb.so.3.8.0 #4 0x7746fdab in lldb_private::process_gdb_remote::ProcessGDBRemote::DisableBreakpointSite(lldb_private::BreakpointSite*) () from /usr/lib/liblldb.so.3.8.0 #5 0x7733938b in std::_Function_handler::_M_invoke(std::_Any_data const&, lldb_private::BreakpointSite*&&) () from /usr/lib/liblldb.so.3.8.0 #6 0x7716ae4f in lldb_private::BreakpointSiteList::ForEach(std::function const&) () from /usr/lib/liblldb.so.3.8.0 #7 0x7733ba9f in lldb_private::Process::DisableAllBreakpointSites() () from /usr/lib/liblldb.so.3.8.0 #8 0x7734a58c in lldb_private::Process::Destroy(bool) () from /usr/lib/liblldb.so.3.8.0 #9 0x7734aa2d in lldb_private::Process::Finalize() () from /usr/lib/liblldb.so.3.8.0 #10 0x771d3fe0 in lldb_private::Debugger::Clear() () from /usr/lib/liblldb.so.3.8.0 #11 0x771d97cf in lldb_private::Debugger::~Debugger() () from /usr/lib/liblldb.so.3.8.0 #12 0x771da0c8 in std::_Sp_counted_ptr::_M_dispose() () from /usr/lib/liblldb.so.3.8.0 #13 0x771cdceb in std::vector, std::allocator > >::~vector() () from /usr/lib/liblldb.so.3.8.0 #14 0x760d9c38 in __run_exit_handlers () from /usr/lib/libc.so.6 #15 0x760d9c85 in exit () from /usr/lib/libc.so.6 #16 0x760c4717 in __libc_start_main () from /usr/lib/libc.so.6 #17 0x4f69 in _start () 2016-03-25 22:42 GMT+01:00 Jim Ingham : > What version of the lldb sources are you working with? I changed the > SBListener over to using only the ListenerSP internally > in r262863. > > Jim > >> On Mar 25, 2016, at 1:03 PM, Paul Peet via lldb-dev >> wrote: >> >> Hey, >> >> I am currently working on lldb bindings for javascript (v8) but it >> seems that the API is giving me some troubles. >> >> What I am doing is to basically wrap SB* objects into V8 objects, and >> since SB objects contain a shared_ptr into an internal class I think I >> can simply copy construct them. >> >> To return a wrapped SB object by some Javascript function, I am simply >> copy constructing the SB object into the wrapper object which is >> dynamically allocated and when the Javascript object is garbage >> collected it will also destroy the SBObject (And also the shared_ptr, >> So it should be save I guess?). >> >> Okay, so far so good but I detected some inconsistency when trying to >> wrap SBListener. The deal was to make SBListener::WaitForEvent >> non-blocking, to do that I am creating a new thread which calls >> WaitForEvents, when it returns and the event is valid, the callbacks >> given from the Javascript code is called. >> >> There is a catch when doing this. I have to track the threads which >> belong to a specific SBListener. But there is not actually easy way to >> do this because SB objects are just simply shared_ptr. I noticed the >> GetSP function which returns the shared_ptr of an SBListener, this >> would be a way to solve this issue as I could use a map which maps the >> internal SBListener pointer to a Class object which manages the thread >> and stuff (SBListenerWorker). >> >> // etc. mutex, ... >>
Re: [lldb-dev] SBListener not using a shared_ptr internally? (Update: Segfault after r262863)
Ah, Thanks adding Debugger::Destroy at the end of my code made the segfaults disappear. Also as far as I understood the lldb code (Core/Debugger.cpp) it should also be possible to call SBDebugger::Terminate() for "destroy" all instances of lldb related objects. 2016-03-28 20:22 GMT+02:00 Jim Ingham : > lldb doesn't currently work if you leave the process of cleaning up to the > C++ destructor chain. You need to call Debugger::Destroy on your way out. > > I think there's a bunch more cleanup than just the broadcaster/listener stuff > before we'll do this right. > > Jim > >> On Mar 28, 2016, at 8:55 AM, Paul Peet wrote: >> >> Hey again, >> >> I've noticing segfaults after r262863 >> (dc5ef2da510f3adba99cd8b2fe18c2e6d417227d). >> Could you try reproducing this bug with this code please? >> >> int main() { >> using namespace lldb; >> >> SBDebugger::Initialize(); >> >> SBDebugger debugger = SBDebugger::Create(true); >> if(!debugger.IsValid()) { >>return 1; >> } >> >> SBTarget target = debugger.CreateTarget("/home/dev/helloWorld/main"); >> if(!target.IsValid()) { >>return 1; >> } >> >> const char* args[] = { "/home/dev/helloWorld/main", 0 }; >> const char* env[] = { 0 }; >> >> SBLaunchInfo launch_info(args); >> launch_info.SetEnvironmentEntries(env, true); >> launch_info.SetWorkingDirectory("/home/dev/helloWorld"); >> launch_info.SetLaunchFlags(eLaunchFlagStopAtEntry); >> >> SBError error; >> SBProcess process = target.Launch(launch_info, error); >> >> return 0; >> } >> >> I tried to build lldb with and without the above commit and it turns >> out that the revision is causing the segfault when simply running that >> code (When it's exiting). >> >> This is the backtrace: >> >> #0 0x55b03b00 in ?? () >> #1 0x771be1aa in >> lldb_private::Broadcaster::BroadcasterImpl::RestoreBroadcaster() () >> from /usr/lib/liblldb.so.3.8.0 >> #2 0x7748b674 in >> lldb_private::process_gdb_remote::GDBRemoteCommunicationClient::SendPacketAndWaitForResponse(char >> const*, unsigned long, StringExtractorGDBRemote&, bool) () from >> /usr/lib/liblldb.so.3.8.0 >> #3 0x7748e89d in >> lldb_private::process_gdb_remote::GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(lldb_private::process_gdb_remote::GDBStoppointType, >> bool, unsigned long, unsigned int) () from /usr/lib/liblldb.so.3.8.0 >> #4 0x7746fdab in >> lldb_private::process_gdb_remote::ProcessGDBRemote::DisableBreakpointSite(lldb_private::BreakpointSite*) >> () from /usr/lib/liblldb.so.3.8.0 >> #5 0x7733938b in std::_Function_handler> (lldb_private::BreakpointSite*), >> lldb_private::Process::DisableAllBreakpointSites()::{lambda(lldb_private::BreakpointSite*)#1}>::_M_invoke(std::_Any_data >> const&, lldb_private::BreakpointSite*&&) () from >> /usr/lib/liblldb.so.3.8.0 >> #6 0x7716ae4f in >> lldb_private::BreakpointSiteList::ForEach(std::function> (lldb_private::BreakpointSite*)> const&) () from >> /usr/lib/liblldb.so.3.8.0 >> #7 0x7733ba9f in >> lldb_private::Process::DisableAllBreakpointSites() () from >> /usr/lib/liblldb.so.3.8.0 >> #8 0x7734a58c in lldb_private::Process::Destroy(bool) () from >> /usr/lib/liblldb.so.3.8.0 >> #9 0x7734aa2d in lldb_private::Process::Finalize() () from >> /usr/lib/liblldb.so.3.8.0 >> #10 0x771d3fe0 in lldb_private::Debugger::Clear() () from >> /usr/lib/liblldb.so.3.8.0 >> #11 0x771d97cf in lldb_private::Debugger::~Debugger() () from >> /usr/lib/liblldb.so.3.8.0 >> #12 0x771da0c8 in >> std::_Sp_counted_ptr> (__gnu_cxx::_Lock_policy)2>::_M_dispose() () from >> /usr/lib/liblldb.so.3.8.0 >> #13 0x00007ffff71cdceb in >> std::vector, >> std::allocator > >::~vector() >> () from /usr/lib/liblldb.so.3.8.0 >> #14 0x760d9c38 in __run_exit_handlers () from /usr/lib/libc.so.6 >> #15 0x760d9c85 in exit () from /usr/lib/libc.so.6 >> #16 0x760c4717 in __libc_start_main () from /usr/lib/libc.so.6 >> #17 0x4f69 in _start () >> >> 2016-03-25 22:42 GMT+01:00 Jim Ingham : >>> What version of the lldb sources are you working with? I changed the >>> SBListener over to using only the ListenerSP internally >>> in r262863. >>> >>> Jim >>> >>>> On Mar 25, 2016, at 1:03 PM, P
[lldb-dev] ReadCStringFromMemory deprecated? (API)
Hey, I noticed that SBProcess::ReadCStringFromMemory uses the deprecated Process::ReadCStringFromMemory function. The note says that it was deprecated in favor of ReadStringFromMemory. Is it possible to add that function to the SBProcess api ? ___ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev