[Lldb-commits] [lldb] r279512 - Fix API usage in TestMultithreaded.test_sb_api_listener_event_process_state
Author: labath Date: Tue Aug 23 07:10:03 2016 New Revision: 279512 URL: http://llvm.org/viewvc/llvm-project?rev=279512&view=rev Log: Fix API usage in TestMultithreaded.test_sb_api_listener_event_process_state The test was attempting to backtrace a process after every state change event (including the "running", and "restarted" ones), which is not a good idea. Modified: lldb/trunk/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp Modified: lldb/trunk/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp?rev=279512&r1=279511&r2=279512&view=diff == --- lldb/trunk/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp (original) +++ lldb/trunk/packages/Python/lldbsuite/test/api/multithreaded/test_listener_event_process_state.cpp Tue Aug 23 07:10:03 2016 @@ -31,6 +31,11 @@ void listener_func() { throw Exception("event is not valid in listener thread"); // send process description SBProcess process = SBProcess::GetProcessFromEvent(event); +if (!process.IsValid()) +throw Exception("process is not valid"); +if (SBProcess::GetStateFromEvent(event) != lldb::eStateStopped || SBProcess::GetRestartedFromEvent(event)) +continue; // Only interested in "stopped" events. + SBStream description; for (int i = 0; i < process.GetNumThreads(); ++i) { ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] r279513 - Fix a crash in GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins
Author: labath Date: Tue Aug 23 07:10:09 2016 New Revision: 279513 URL: http://llvm.org/viewvc/llvm-project?rev=279513&view=rev Log: Fix a crash in GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins The function was attempting to write the reply to the log even if the reply was empty. Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=279513&r1=279512&r2=279513&view=diff == --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Tue Aug 23 07:10:09 2016 @@ -3975,7 +3975,7 @@ GDBRemoteCommunicationClient::GetSupport __FUNCTION__); } -if (log && m_supported_async_json_packets_is_valid) +if (log && m_supported_async_json_packets_sp) { StreamString stream; m_supported_async_json_packets_sp->Dump(stream); ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D23802: gdb-remote: Make the sequence mutex non-recursive
labath created this revision. labath added a reviewer: clayborg. labath added a subscriber: lldb-commits. This is a preparatory commit for D22914, where I'd like to replace this mutex by an R/W lock (which is also not recursive). This required a couple of changes: - Read/WriteRegister expect the caller to obtain the mutex and are renamed to reflect that. The only caller of these functions is the GDBRemoteRegisterContext class, which already acquired that mutex (for the most part), so the changes there are minimal. (It is not clear to me whether this function actually needs to take the lock. The thing which this lock seems to protect is the state of the register context if it is being accessed from multiple threads, which, if true, sounds like it could be done by a separate mutex.) - GetThreadSuffixSupported() was being called from locked and unlocked contexts (including contexts where the process was running, and the call would fail if it did not have the result cached). I have split this into two functions, one which computes the thread suffix support and caches it (this one always takes the lock), and another, which returns the cached value (and never needs to take the lock). This feels quite natural as ProcessGdbRemote was already pre-caching this value at the start. https://reviews.llvm.org/D23802 Files: source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp Index: unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp === --- unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp +++ unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp @@ -76,17 +76,23 @@ if (HasFailure()) return; +std::future suffix_result = std::async(std::launch::async, [&] { client.ComputeThreadSuffixSupport(); }); +Handle_QThreadSuffixSupported(server, true); +suffix_result.get(); + +GDBRemoteCommunicationClient::Lock lock(client, false); +ASSERT_TRUE(bool(lock)); + const lldb::tid_t tid = 0x47; const uint32_t reg_num = 4; std::future write_result = -std::async(std::launch::async, [&] { return client.WriteRegister(tid, reg_num, one_register); }); +std::async(std::launch::async, [&] { return client.WriteRegisterNoLock(tid, reg_num, one_register); }); -Handle_QThreadSuffixSupported(server, true); HandlePacket(server, "P4=" + one_register_hex + ";thread:0047;", "OK"); ASSERT_TRUE(write_result.get()); -write_result = std::async(std::launch::async, [&] { return client.WriteAllRegisters(tid, all_registers); }); +write_result = std::async(std::launch::async, [&] { return client.WriteAllRegistersNoLock(tid, all_registers); }); HandlePacket(server, "G" + all_registers_hex + ";thread:0047;", "OK"); ASSERT_TRUE(write_result.get()); @@ -100,17 +106,23 @@ if (HasFailure()) return; +std::future suffix_result = std::async(std::launch::async, [&] { client.ComputeThreadSuffixSupport(); }); +Handle_QThreadSuffixSupported(server, false); +suffix_result.get(); + +GDBRemoteCommunicationClient::Lock lock(client, false); +ASSERT_TRUE(bool(lock)); + const lldb::tid_t tid = 0x47; const uint32_t reg_num = 4; std::future write_result = -std::async(std::launch::async, [&] { return client.WriteRegister(tid, reg_num, one_register); }); +std::async(std::launch::async, [&] { return client.WriteRegisterNoLock(tid, reg_num, one_register); }); -Handle_QThreadSuffixSupported(server, false); HandlePacket(server, "Hg47", "OK"); HandlePacket(server, "P4=" + one_register_hex, "OK"); ASSERT_TRUE(write_result.get()); -write_result = std::async(std::launch::async, [&] { return client.WriteAllRegisters(tid, all_registers); }); +write_result = std::async(std::launch::async, [&] { return client.WriteAllRegistersNoLock(tid, all_registers); }); HandlePacket(server, "G" + all_registers_hex, "OK"); ASSERT_TRUE(write_result.get()); @@ -124,21 +136,24 @@ if (HasFailure()) return; +std::future suffix_result = std::async(std::launch::async, [&] { client.ComputeThreadSuffixSupport(); }); +Handle_QThreadSuffixSupported(server, true); +suffix_result.get(); + const lldb::tid_t tid = 0x47; const uint32_t reg_num = 4; std::future async_result = std::async(std::launch::async, [&] { return client.GetpPacketSupported(tid); }); -Handle_QThreadSuffixSupported(server, true); HandlePacket(server, "p0;thread:0047;",
Re: [Lldb-commits] [PATCH] D23802: gdb-remote: Make the sequence mutex non-recursive
clayborg added a comment. The old mutex was there so that you could send a packet and get a result without worrying about other threads getting your response. It was recursive for the case where we needed to send two packets as one (set thread ID, then send packet), and for reading all registers (as you have found), so your patch does work, but it now only for these special cases. Now there is no way to easily take the mutex and send 5 different packets without going and adding new NoLock variants of each call that you might want to send as a single stream of packets. Can we think slightly cleaner way to do this? Before you could stake the sequence mutex in your main function that wanted to make N calls, and each call would then recursively lock the mutex and everything just worked. Now you will deadlock if you do things incorrectly (granted you will need to do a "GDBRemoteClientBase::Lock lock(gdb_comm, false);" followed by a "m_gdb_comm.SendSomePacket()". https://reviews.llvm.org/D23802 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] r279533 - Change the PathMappingList::FindFile to use FileSpec API's
Author: jingham Date: Tue Aug 23 12:13:33 2016 New Revision: 279533 URL: http://llvm.org/viewvc/llvm-project?rev=279533&view=rev Log: Change the PathMappingList::FindFile to use FileSpec API's Also, when appending path components, collapse multiple "/" into one at the join. Modified: lldb/trunk/source/Host/common/FileSpec.cpp lldb/trunk/source/Target/PathMappingList.cpp lldb/trunk/unittests/Host/FileSpecTest.cpp Modified: lldb/trunk/source/Host/common/FileSpec.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=279533&r1=279532&r2=279533&view=diff == --- lldb/trunk/source/Host/common/FileSpec.cpp (original) +++ lldb/trunk/source/Host/common/FileSpec.cpp Tue Aug 23 12:13:33 2016 @@ -1552,6 +1552,9 @@ FileSpec::AppendPathComponent(const char stream.PutChar(GetPrefferedPathSeparator(m_syntax)); } +while (IsPathSeparator(new_path[0], m_syntax)) +new_path++; + stream.PutCString(new_path); const bool resolve = false; Modified: lldb/trunk/source/Target/PathMappingList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/PathMappingList.cpp?rev=279533&r1=279532&r2=279533&view=diff == --- lldb/trunk/source/Target/PathMappingList.cpp (original) +++ lldb/trunk/source/Target/PathMappingList.cpp Tue Aug 23 12:13:33 2016 @@ -224,6 +224,7 @@ PathMappingList::ReverseRemapPath (const for (const auto& it : m_pairs) { +// FIXME: This should be using FileSpec API's to do the path appending. const size_t prefixLen = it.second.GetLength(); if (::strncmp (it.second.GetCString(), path_cstr, prefixLen) == 0) { @@ -242,7 +243,6 @@ PathMappingList::FindFile (const FileSpe if (!m_pairs.empty()) { char orig_path[PATH_MAX]; -char new_path[PATH_MAX]; const size_t orig_path_len = orig_spec.GetPath (orig_path, sizeof(orig_path)); if (orig_path_len > 0) { @@ -255,13 +255,10 @@ PathMappingList::FindFile (const FileSpe { if (::strncmp (pos->first.GetCString(), orig_path, prefix_len) == 0) { -const size_t new_path_len = snprintf(new_path, sizeof(new_path), "%s/%s", pos->second.GetCString(), orig_path + prefix_len); -if (new_path_len < sizeof(new_path)) -{ -new_spec.SetFile (new_path, true); -if (new_spec.Exists()) -return true; -} +new_spec.SetFile(pos->second.GetCString(), false); +new_spec.AppendPathComponent(orig_path+prefix_len); +if (new_spec.Exists()) +return true; } } } Modified: lldb/trunk/unittests/Host/FileSpecTest.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Host/FileSpecTest.cpp?rev=279533&r1=279532&r2=279533&view=diff == --- lldb/trunk/unittests/Host/FileSpecTest.cpp (original) +++ lldb/trunk/unittests/Host/FileSpecTest.cpp Tue Aug 23 12:13:33 2016 @@ -69,6 +69,12 @@ TEST(FileSpecTest, AppendPathComponent) EXPECT_STREQ("/foo", fs_posix.GetDirectory().GetCString()); EXPECT_STREQ("bar", fs_posix.GetFilename().GetCString()); +FileSpec fs_posix_2("/foo", false, FileSpec::ePathSyntaxPosix); +fs_posix_2.AppendPathComponent("//bar/baz"); +EXPECT_STREQ("/foo/bar/baz", fs_posix_2.GetCString()); +EXPECT_STREQ("/foo/bar", fs_posix_2.GetDirectory().GetCString()); +EXPECT_STREQ("baz", fs_posix_2.GetFilename().GetCString()); + FileSpec fs_windows("F:\\bar", false, FileSpec::ePathSyntaxWindows); fs_windows.AppendPathComponent("baz"); EXPECT_STREQ("F:\\bar\\baz", fs_windows.GetCString()); ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
Re: [Lldb-commits] [PATCH] D23802: gdb-remote: Make the sequence mutex non-recursive
labath added a comment. In https://reviews.llvm.org/D23802#523244, @clayborg wrote: > The old mutex was there so that you could send a packet and get a result > without worrying about other threads getting your response. It was recursive > for the case where we needed to send two packets as one (set thread ID, then > send packet), and for reading all registers (as you have found), so your > patch does work, but it now only for these special cases. Now there is no way > to easily take the mutex and send 5 different packets without going and > adding new NoLock variants of each call that you might want to send as a > single stream of packets. Can we think slightly cleaner way to do this? > Before you could stake the sequence mutex in your main function that wanted > to make N calls, and each call would then recursively lock the mutex and > everything just worked. Now you will deadlock if you do things incorrectly > (granted you will need to do a "GDBRemoteClientBase::Lock lock(gdb_comm, > false);" followed by a "m_gdb_comm.SendSomePacket()". I see what you mean. I have considered a couple of other options, but none of them struck me as obviously best. Alternatives I see are: - have all functions (or just those that we need right now) take an optional `lock` boolean parameter (probably defaulting to true). If it is set the function takes a lock, if not, it doesn't. The main downside I see here is that then the locking behaviour would depend on the run-time parameter, which is not completely ideal. OTOH, it would sort of sit along nicely with the "send_async" parameter, which also controls behavior in a similar way. - just make all functions `NoLock` and require the user to lock manually. The tricky part here is that unlike a normal lock, locking the packet lock can fail, so you end up with code like `Lock lock; if(!lock) {if(log) log->Printf("getting registers failed");} else { ... }`, which doesn't look nice but we could make it better. If we move the logging part into the `Lock` object, then this would end up with: `Lock lock(gdb_comm, false, "getting registers"); if (!lock) return; ...` which I don't think is too bad. - like before, but only do it for functions which are used from locked and unlocked contexts. Then the policy would be that if you need a NoLock version of a function, instead of creating a new one, you rename the current one and change all callers (I don't expect that there will be so many of them) to lock explicitly. This does not require any major rewrite, but it is a bit messy because you have two kinds of functions. (This is not really an alternative, just an extension of the current approach.) - write our own implementation of a **recursive** read/write lock. This may not be so difficult even (although I can see how some edge cases might be tricky -- e.g. we have a read lock (so we can share the connection with other threads), but then we need to send a packet which wants exclusive access), and it would nicely compartmentalize all the ugliness. However, I am kinda against inventing locking primitives (even though the Lock class is such a thing, but there I think it was justified). What do you think? https://reviews.llvm.org/D23802 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] r279540 - Implementation "step out" plans shouldn't gather the return value.
Author: jingham Date: Tue Aug 23 12:55:21 2016 New Revision: 279540 URL: http://llvm.org/viewvc/llvm-project?rev=279540&view=rev Log: Implementation "step out" plans shouldn't gather the return value. When, for instance, "step-in" steps into a function that it doesn't want to stop in (e.g. has no debug info) it will push a step-out plan to implement the step out so it can then continue stepping. These step out's don't use the result of the function stepped out of, so they shouldn't spend the time to compute it. Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h lldb/trunk/source/Target/Thread.cpp lldb/trunk/source/Target/ThreadPlanStepOut.cpp Modified: lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h?rev=279540&r1=279539&r2=279540&view=diff == --- lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h (original) +++ lldb/trunk/include/lldb/Target/ThreadPlanStepOut.h Tue Aug 23 12:55:21 2016 @@ -32,7 +32,8 @@ public: Vote run_vote, uint32_t frame_idx, LazyBool step_out_avoids_code_without_debug_info, - bool continue_to_next_branch = false); + bool continue_to_next_branch = false, + bool gather_return_value = true); ~ThreadPlanStepOut() override; @@ -46,11 +47,12 @@ public: void DidPush() override; bool IsPlanStale() override; -lldb::ValueObjectSP GetReturnValueObject() override +lldb::ValueObjectSP +GetReturnValueObject() override { return m_return_valobj_sp; } - + protected: void SetFlagsToDefault() override @@ -65,18 +67,19 @@ protected: private: static uint32_t s_default_flag_values; // These are the default flag values for the ThreadPlanStepThrough. -lldb::addr_t m_step_from_insn; -StackID m_step_out_to_id; -StackID m_immediate_step_from_id; -lldb::break_id_t m_return_bp_id; -lldb::addr_t m_return_addr; -bool m_stop_others; -lldb::ThreadPlanSP m_step_out_to_inline_plan_sp;// This plan implements step out to the real function containing +lldb::addr_tm_step_from_insn; +StackID m_step_out_to_id; +StackID m_immediate_step_from_id; +lldb::break_id_tm_return_bp_id; +lldb::addr_tm_return_addr; +boolm_stop_others; +lldb::ThreadPlanSP m_step_out_to_inline_plan_sp;// This plan implements step out to the real function containing // an inlined frame so we can then step out of that. -lldb::ThreadPlanSP m_step_through_inline_plan_sp; // This plan then steps past the inlined frame(s). -lldb::ThreadPlanSP m_step_out_further_plan_sp; // This plan keeps stepping out if ShouldStopHere told us to. -Function *m_immediate_step_from_function; +lldb::ThreadPlanSP m_step_through_inline_plan_sp; // This plan then steps past the inlined frame(s). +lldb::ThreadPlanSP m_step_out_further_plan_sp; // This plan keeps stepping out if ShouldStopHere told us to. +Function *m_immediate_step_from_function; lldb::ValueObjectSP m_return_valobj_sp; +boolm_calculate_return_value; friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepOut (bool abort_other_plans, Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=279540&r1=279539&r2=279540&view=diff == --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Tue Aug 23 12:55:21 2016 @@ -1626,6 +1626,7 @@ Thread::QueueThreadPlanForStepOutNoShoul uint32_t frame_idx, bool continue_to_next_branch) { +const bool calculate_return_value = false; // No need to calculate the return value here. ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut (*this, addr_context, first_insn, @@ -1634,7 +1635,8 @@ Thread::QueueThreadPlanForStepOutNoShoul run_vote, frame_idx, eLazyBoolNo, - continue_to_next_branch)); + continue_to_next_branch, + calculate_return_value)); ThreadPlanStepOut *new_p
Re: [Lldb-commits] [PATCH] D23802: gdb-remote: Make the sequence mutex non-recursive
clayborg requested changes to this revision. clayborg added a comment. This revision now requires changes to proceed. Maybe instead of "NoLock" on the functions we those functions take an extra argument? Then someone can't accidentally run one of those without locking. We need to somehow enforce that locking must occur. Maybe passing an extra: const GDBRemoteClientBase::Lock &lock Making it const can stop people from locking it in the NoLock functions, and we can maybe assert: bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid, const GDBRemoteClientBase::Lock &lock) { assert(lock.IsAcquired()); Then IsAcquired() can be const, but this at least would enforce that someone needs to lock before sending the packet. We probably need to document these no locking commands and let users know they must lock and pass in the lock for verification. https://reviews.llvm.org/D23802 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] Fix warnings preventing copy elision.
Summary: Moving a temporary object prevents copy elision, which is exactly what clang points out by warning about this pattern. The fix is simply removal of std::move applied to temporary objects. Differential Revision: https://reviews.llvm.org/D23825 --- tools/debugserver/source/JSON.cpp | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/debugserver/source/JSON.cpp b/tools/debugserver/source/JSON.cpp index e7e0423..9d56d19 100644 --- a/tools/debugserver/source/JSON.cpp +++ b/tools/debugserver/source/JSON.cpp @@ -372,7 +372,7 @@ JSONParser::GetToken (std::string &value) if (escaped_ch == -1) { error << "error: an error occurred getting a character from offset "
[Lldb-commits] [PATCH] Fix warnings preventing copy elision.
Summary: Moving a temporary object prevents copy elision, which is exactly what clang points out by warning about this pattern. The fix is simply removal of std::move applied to temporary objects. Differential Revision: https://reviews.llvm.org/D23825 --- tools/debugserver/source/JSON.cpp | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/debugserver/source/JSON.cpp b/tools/debugserver/source/JSON.cpp index e7e0423..9d56d19 100644 --- a/tools/debugserver/source/JSON.cpp +++ b/tools/debugserver/source/JSON.cpp @@ -372,7 +372,7 @@ JSONParser::GetToken (std::string &value) if (escaped_ch == -1) { error << "error: an error occurred getting a character from offset "
[Lldb-commits] [lldb] r279611 - Add api logging for SBDebugger::SetCurrentPlatformSDKRoot.
Author: jmolenda Date: Wed Aug 24 00:25:32 2016 New Revision: 279611 URL: http://llvm.org/viewvc/llvm-project?rev=279611&view=rev Log: Add api logging for SBDebugger::SetCurrentPlatformSDKRoot. Modified: lldb/trunk/source/API/SBDebugger.cpp Modified: lldb/trunk/source/API/SBDebugger.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=279611&r1=279610&r2=279611&view=diff == --- lldb/trunk/source/API/SBDebugger.cpp (original) +++ lldb/trunk/source/API/SBDebugger.cpp Wed Aug 24 00:25:32 2016 @@ -1228,12 +1228,15 @@ SBDebugger::SetCurrentPlatform (const ch bool SBDebugger::SetCurrentPlatformSDKRoot (const char *sysroot) { +Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (m_opaque_sp) { PlatformSP platform_sp (m_opaque_sp->GetPlatformList().GetSelectedPlatform()); if (platform_sp) { +if (log && sysroot) +log->Printf ("SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")", sysroot); platform_sp->SetSDKRootDirectory (ConstString (sysroot)); return true; } ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits