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 <paulpee...@gmail.com> 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 0x0000555555b03b00 in ?? () > #1 0x00007ffff71be1aa in > lldb_private::Broadcaster::BroadcasterImpl::RestoreBroadcaster() () > from /usr/lib/liblldb.so.3.8.0 > #2 0x00007ffff748b674 in > lldb_private::process_gdb_remote::GDBRemoteCommunicationClient::SendPacketAndWaitForResponse(char > const*, unsigned long, StringExtractorGDBRemote&, bool) () from > /usr/lib/liblldb.so.3.8.0 > #3 0x00007ffff748e89d 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 0x00007ffff746fdab in > lldb_private::process_gdb_remote::ProcessGDBRemote::DisableBreakpointSite(lldb_private::BreakpointSite*) > () from /usr/lib/liblldb.so.3.8.0 > #5 0x00007ffff733938b in std::_Function_handler<void > (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 0x00007ffff716ae4f in > lldb_private::BreakpointSiteList::ForEach(std::function<void > (lldb_private::BreakpointSite*)> const&) () from > /usr/lib/liblldb.so.3.8.0 > #7 0x00007ffff733ba9f in > lldb_private::Process::DisableAllBreakpointSites() () from > /usr/lib/liblldb.so.3.8.0 > #8 0x00007ffff734a58c in lldb_private::Process::Destroy(bool) () from > /usr/lib/liblldb.so.3.8.0 > #9 0x00007ffff734aa2d in lldb_private::Process::Finalize() () from > /usr/lib/liblldb.so.3.8.0 > #10 0x00007ffff71d3fe0 in lldb_private::Debugger::Clear() () from > /usr/lib/liblldb.so.3.8.0 > #11 0x00007ffff71d97cf in lldb_private::Debugger::~Debugger() () from > /usr/lib/liblldb.so.3.8.0 > #12 0x00007ffff71da0c8 in > std::_Sp_counted_ptr<lldb_private::Debugger*, > (__gnu_cxx::_Lock_policy)2>::_M_dispose() () from > /usr/lib/liblldb.so.3.8.0 > #13 0x00007ffff71cdceb in > std::vector<std::shared_ptr<lldb_private::Debugger>, > std::allocator<std::shared_ptr<lldb_private::Debugger> > >::~vector() > () from /usr/lib/liblldb.so.3.8.0 > #14 0x00007ffff60d9c38 in __run_exit_handlers () from /usr/lib/libc.so.6 > #15 0x00007ffff60d9c85 in exit () from /usr/lib/libc.so.6 > #16 0x00007ffff60c4717 in __libc_start_main () from /usr/lib/libc.so.6 > #17 0x0000555555554f69 in _start () > > 2016-03-25 22:42 GMT+01:00 Jim Ingham <jing...@apple.com>: >> 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 >>> <lldb-dev@lists.llvm.org> 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<void*, SBListenerWorker*> 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<void*>(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