[Lldb-commits] [lldb] r313371 - Remove a couple of warnings pointed out by Ted Woodward.
Author: jingham Date: Fri Sep 15 10:54:37 2017 New Revision: 313371 URL: http://llvm.org/viewvc/llvm-project?rev=313371&view=rev Log: Remove a couple of warnings pointed out by Ted Woodward. Modified: lldb/trunk/source/API/SBBreakpointName.cpp Modified: lldb/trunk/source/API/SBBreakpointName.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBreakpointName.cpp?rev=313371&r1=313370&r2=313371&view=diff == --- lldb/trunk/source/API/SBBreakpointName.cpp (original) +++ lldb/trunk/source/API/SBBreakpointName.cpp Fri Sep 15 10:54:37 2017 @@ -77,15 +77,15 @@ public: // For now we take a simple approach and only keep the name, and relook // up the location when we need it. - TargetSP GetTarget() { + TargetSP GetTarget() const { return m_target_wp.lock(); } - const char *GetName() { + const char *GetName() const { return m_name.c_str(); } - bool IsValid() { + bool IsValid() const { return !m_name.empty() && m_target_wp.lock(); } @@ -102,7 +102,13 @@ public: const lldb_private::BreakpointName *GetBreakpointName() const { -return GetBreakpointName(); +if (!IsValid()) + return nullptr; +TargetSP target_sp = GetTarget(); +if (!target_sp) + return nullptr; +Status error; +return target_sp->FindBreakpointName(ConstString(m_name), true, error); } private: @@ -339,7 +345,7 @@ bool SBBreakpointName::GetAutoContinue() BreakpointName *bp_name = GetBreakpointName(); if (!bp_name) -return nullptr; +return false; LLDB_LOG(log, "Name: {0}\n", bp_name->GetName()); std::lock_guard guard( ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37923: Implement interactive command interruption
lemo created this revision. Herald added a subscriber: ki.stfu. The core of this change is the new CommandInterpreter::m_command_state, which models the state transitions for interactive commands, including an "interrupted" state transition. In general, command interruption requires cooperation from the code executing the command, which needs to poll for interruption requests through CommandInterpreter::WasInterrupted(). CommandInterpreter::PrintCommandOutput() implements an optionally interruptible printing of the command output, which for large outputs was likely the longest blocking part (ex. target modules dump symtab on a complex binary could take 10+ minutes) Also included are a few fixes in the handlers for SIGINT (thread safety and using the signal-safe _exit() instead of exit()) https://reviews.llvm.org/D37923 Files: include/lldb/Core/IOHandler.h include/lldb/Interpreter/CommandInterpreter.h source/Commands/CommandObjectTarget.cpp source/Interpreter/CommandInterpreter.cpp tools/driver/Driver.cpp tools/lldb-mi/MIDriverMain.cpp Index: tools/lldb-mi/MIDriverMain.cpp === --- tools/lldb-mi/MIDriverMain.cpp +++ tools/lldb-mi/MIDriverMain.cpp @@ -72,14 +72,13 @@ #ifdef _WIN32 // Restore handler as it is not persistent on Windows signal(SIGINT, sigint_handler); #endif - static bool g_interrupt_sent = false; + static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT; CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance(); lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger(); if (pDebugger != nullptr) { -if (!g_interrupt_sent) { - g_interrupt_sent = true; +if (!g_interrupt_sent.test_and_set()) { pDebugger->DispatchInputInterrupt(); - g_interrupt_sent = false; + g_interrupt_sent.clear(); } } Index: tools/driver/Driver.cpp === --- tools/driver/Driver.cpp +++ tools/driver/Driver.cpp @@ -1177,17 +1177,16 @@ } void sigint_handler(int signo) { - static bool g_interrupt_sent = false; + static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT; if (g_driver) { -if (!g_interrupt_sent) { - g_interrupt_sent = true; +if (!g_interrupt_sent.test_and_set()) { g_driver->GetDebugger().DispatchInputInterrupt(); - g_interrupt_sent = false; + g_interrupt_sent.clear(); return; } } - exit(signo); + _exit(signo); } void sigtstp_handler(int signo) { Index: source/Interpreter/CommandInterpreter.cpp === --- source/Interpreter/CommandInterpreter.cpp +++ source/Interpreter/CommandInterpreter.cpp @@ -2677,6 +2677,58 @@ return total_bytes; } +void CommandInterpreter::StartHandlingCommand() { + auto prev_state = m_command_state.exchange(CommandHandlingState::eInProgress); + assert(prev_state == CommandHandlingState::eIdle); +} + +void CommandInterpreter::FinishHandlingCommand() { + auto prev_state = m_command_state.exchange(CommandHandlingState::eIdle); + assert(prev_state != CommandHandlingState::eIdle); +} + +bool CommandInterpreter::InterruptCommand() { + auto in_progress = CommandHandlingState::eInProgress; + return m_command_state.compare_exchange_strong( + in_progress, CommandHandlingState::eInterrupted); +} + +bool CommandInterpreter::WasInterrupted() const { + return m_command_state == CommandHandlingState::eInterrupted; +} + +void CommandInterpreter::PrintCommandOutput(Stream &stream, llvm::StringRef str, +bool interruptible) { + if (str.empty()) { +return; + } + + if (interruptible) { +// Split the output into lines and poll for interrupt requests +const char *data = str.data(); +size_t size = str.size(); +while (size > 0 && !WasInterrupted()) { + size_t chunk_size = 0; + for (; chunk_size < size; ++chunk_size) { +assert(data[chunk_size] != '\0'); +if (data[chunk_size] == '\n') { + ++chunk_size; + break; +} + } + chunk_size = stream.Write(data, chunk_size); + assert(size >= chunk_size); + data += chunk_size; + size -= chunk_size; +} +if (size > 0) { + stream.Printf("\n... Interrupted.\n"); +} + } else { +stream.PutCString(str); + } +} + void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, std::string &line) { const bool is_interactive = io_handler.GetIsInteractive(); @@ -2700,6 +2752,8 @@ line.c_str()); } + StartHandlingCommand(); + lldb_private::CommandReturnObject result; HandleCommand(line.c_str(), eLazyBoolCalculate, result); @@ -2710,18 +2764,20 @@ if (!result.GetImmediateOutputStream()) { llvm::StringRef output = result.GetOutputData(); - if (!o
[Lldb-commits] [PATCH] D37923: Implement interactive command interruption
amccarth added a comment. I haven't looked at the whole patch yet, but it seems the SIGINT fix is well isolated. That should probably be in a separate patch. https://reviews.llvm.org/D37923 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37926: Fix the SIGINT handlers
lemo created this revision. Herald added a subscriber: ki.stfu. 1. Fix a data race (g_interrupt_sent flag usage was not thread safe, signals can be handled on arbitrary threads) 2. exit() is not signal-safe, replaced it with the signal-safe equivalent _exit() https://reviews.llvm.org/D37926 Files: driver/Driver.cpp lldb-mi/MIDriverMain.cpp Index: lldb-mi/MIDriverMain.cpp === --- lldb-mi/MIDriverMain.cpp +++ lldb-mi/MIDriverMain.cpp @@ -72,14 +72,13 @@ #ifdef _WIN32 // Restore handler as it is not persistent on Windows signal(SIGINT, sigint_handler); #endif - static bool g_interrupt_sent = false; + static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT; CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance(); lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger(); if (pDebugger != nullptr) { -if (!g_interrupt_sent) { - g_interrupt_sent = true; +if (!g_interrupt_sent.test_and_set()) { pDebugger->DispatchInputInterrupt(); - g_interrupt_sent = false; + g_interrupt_sent.clear(); } } Index: driver/Driver.cpp === --- driver/Driver.cpp +++ driver/Driver.cpp @@ -1177,17 +1177,16 @@ } void sigint_handler(int signo) { - static bool g_interrupt_sent = false; + static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT; if (g_driver) { -if (!g_interrupt_sent) { - g_interrupt_sent = true; +if (!g_interrupt_sent.test_and_set()) { g_driver->GetDebugger().DispatchInputInterrupt(); - g_interrupt_sent = false; + g_interrupt_sent.clear(); return; } } - exit(signo); + _exit(signo); } void sigtstp_handler(int signo) { Index: lldb-mi/MIDriverMain.cpp === --- lldb-mi/MIDriverMain.cpp +++ lldb-mi/MIDriverMain.cpp @@ -72,14 +72,13 @@ #ifdef _WIN32 // Restore handler as it is not persistent on Windows signal(SIGINT, sigint_handler); #endif - static bool g_interrupt_sent = false; + static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT; CMIDriverMgr &rDriverMgr = CMIDriverMgr::Instance(); lldb::SBDebugger *pDebugger = rDriverMgr.DriverGetTheDebugger(); if (pDebugger != nullptr) { -if (!g_interrupt_sent) { - g_interrupt_sent = true; +if (!g_interrupt_sent.test_and_set()) { pDebugger->DispatchInputInterrupt(); - g_interrupt_sent = false; + g_interrupt_sent.clear(); } } Index: driver/Driver.cpp === --- driver/Driver.cpp +++ driver/Driver.cpp @@ -1177,17 +1177,16 @@ } void sigint_handler(int signo) { - static bool g_interrupt_sent = false; + static std::atomic_flag g_interrupt_sent = ATOMIC_FLAG_INIT; if (g_driver) { -if (!g_interrupt_sent) { - g_interrupt_sent = true; +if (!g_interrupt_sent.test_and_set()) { g_driver->GetDebugger().DispatchInputInterrupt(); - g_interrupt_sent = false; + g_interrupt_sent.clear(); return; } } - exit(signo); + _exit(signo); } void sigtstp_handler(int signo) { ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37923: Implement interactive command interruption
lemo updated this revision to Diff 115476. lemo added a comment. Split the SIGINT handles fixes into a stanalone patch https://reviews.llvm.org/D37923 Files: include/lldb/Core/IOHandler.h include/lldb/Interpreter/CommandInterpreter.h source/Commands/CommandObjectTarget.cpp source/Interpreter/CommandInterpreter.cpp Index: source/Interpreter/CommandInterpreter.cpp === --- source/Interpreter/CommandInterpreter.cpp +++ source/Interpreter/CommandInterpreter.cpp @@ -2677,6 +2677,58 @@ return total_bytes; } +void CommandInterpreter::StartHandlingCommand() { + auto prev_state = m_command_state.exchange(CommandHandlingState::eInProgress); + assert(prev_state == CommandHandlingState::eIdle); +} + +void CommandInterpreter::FinishHandlingCommand() { + auto prev_state = m_command_state.exchange(CommandHandlingState::eIdle); + assert(prev_state != CommandHandlingState::eIdle); +} + +bool CommandInterpreter::InterruptCommand() { + auto in_progress = CommandHandlingState::eInProgress; + return m_command_state.compare_exchange_strong( + in_progress, CommandHandlingState::eInterrupted); +} + +bool CommandInterpreter::WasInterrupted() const { + return m_command_state == CommandHandlingState::eInterrupted; +} + +void CommandInterpreter::PrintCommandOutput(Stream &stream, llvm::StringRef str, +bool interruptible) { + if (str.empty()) { +return; + } + + if (interruptible) { +// Split the output into lines and poll for interrupt requests +const char *data = str.data(); +size_t size = str.size(); +while (size > 0 && !WasInterrupted()) { + size_t chunk_size = 0; + for (; chunk_size < size; ++chunk_size) { +assert(data[chunk_size] != '\0'); +if (data[chunk_size] == '\n') { + ++chunk_size; + break; +} + } + chunk_size = stream.Write(data, chunk_size); + assert(size >= chunk_size); + data += chunk_size; + size -= chunk_size; +} +if (size > 0) { + stream.Printf("\n... Interrupted.\n"); +} + } else { +stream.PutCString(str); + } +} + void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, std::string &line) { const bool is_interactive = io_handler.GetIsInteractive(); @@ -2700,6 +2752,8 @@ line.c_str()); } + StartHandlingCommand(); + lldb_private::CommandReturnObject result; HandleCommand(line.c_str(), eLazyBoolCalculate, result); @@ -2710,18 +2764,20 @@ if (!result.GetImmediateOutputStream()) { llvm::StringRef output = result.GetOutputData(); - if (!output.empty()) -io_handler.GetOutputStreamFile()->PutCString(output); + PrintCommandOutput(*io_handler.GetOutputStreamFile(), output, + is_interactive); } // Now emit the command error text from the command we just executed if (!result.GetImmediateErrorStream()) { llvm::StringRef error = result.GetErrorData(); - if (!error.empty()) -io_handler.GetErrorStreamFile()->PutCString(error); + PrintCommandOutput(*io_handler.GetErrorStreamFile(), error, + is_interactive); } } + FinishHandlingCommand(); + switch (result.GetStatus()) { case eReturnStatusInvalid: case eReturnStatusSuccessFinishNoResult: @@ -2777,6 +2833,10 @@ ExecutionContext exe_ctx(GetExecutionContext()); Process *process = exe_ctx.GetProcessPtr(); + if (InterruptCommand()) { +return true; + } + if (process) { StateType state = process->GetState(); if (StateIsRunningState(state)) { Index: source/Commands/CommandObjectTarget.cpp === --- source/Commands/CommandObjectTarget.cpp +++ source/Commands/CommandObjectTarget.cpp @@ -2053,6 +2053,9 @@ result.GetOutputStream().EOL(); result.GetOutputStream().EOL(); } +if (m_interpreter.WasInterrupted()) { + break; +} num_dumped++; DumpModuleSymtab( m_interpreter, result.GetOutputStream(), @@ -2081,6 +2084,9 @@ result.GetOutputStream().EOL(); result.GetOutputStream().EOL(); } +if (m_interpreter.WasInterrupted()) { + break; +} num_dumped++; DumpModuleSymtab(m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order); @@ -2146,6 +2152,9 @@ " modules.\n", (uint64_t)num_modules); for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { +if (m_interpreter.WasInterrupted
[Lldb-commits] [PATCH] D37926: Fix the SIGINT handlers
zturner added a comment. It turns out the function this called, `DispatchInputInterrupt`, already acquires a mutex. Maybe put the synchronization in there? Then you don't have to reproduce the synchronization in both MI and LLDB https://reviews.llvm.org/D37926 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
Re: [Lldb-commits] [PATCH] D37926: Fix the SIGINT handlers
How would that fix look? If the intention is to ignore nested SIGINT then doing it directly in the handler seems cleaner and safer (re. safety, note that m_input_reader_stack.GetMutex() is a std::*recursive_*mutex so depending on it in signal handlers is a big no-no. The recursive_mutex looks like a red flag in itself, but that's something for another day) On Fri, Sep 15, 2017 at 1:34 PM, Zachary Turner via Phabricator < revi...@reviews.llvm.org> wrote: > zturner added a comment. > > It turns out the function this called, `DispatchInputInterrupt`, already > acquires a mutex. Maybe put the synchronization in there? Then you don't > have to reproduce the synchronization in both MI and LLDB > > > https://reviews.llvm.org/D37926 > > > > ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37923: Implement interactive command interruption
amccarth added inline comments. Comment at: source/Commands/CommandObjectTarget.cpp:2058 + break; +} num_dumped++; Many LLVM developers prefer to omit the braces when the body of the control-flow statement is a single statement. Comment at: source/Interpreter/CommandInterpreter.cpp:2713 + for (; chunk_size < size; ++chunk_size) { +assert(data[chunk_size] != '\0'); +if (data[chunk_size] == '\n') { Should we be that trusting of a caller? In a non-debug build, if a caller doesn't end the (non-empty) string with '\n', this'll just run past the end of the buffer. Did I miss something that guarantees the caller won't make a mistake? Would it be too expensive to play it safe? Comment at: source/Interpreter/CommandInterpreter.cpp:2720 + chunk_size = stream.Write(data, chunk_size); + assert(size >= chunk_size); + data += chunk_size; This assert should precede the line before it. Comment at: tools/driver/Driver.cpp:1182 if (g_driver) { -if (!g_interrupt_sent) { - g_interrupt_sent = true; +if (!g_interrupt_sent.test_and_set()) { g_driver->GetDebugger().DispatchInputInterrupt(); I'm not sure why these two ifs aren't one, as in: ``` if (g_driver && !g_interrupt_sent.test_and_set()) ``` Comment at: tools/driver/Driver.cpp:1189 - exit(signo); + _exit(signo); } Can you add a comment explaining why this uses `_exit` rather than `exit`? It's not obvious to me. Comment at: tools/lldb-mi/MIDriverMain.cpp:71 //-- void sigint_handler(int vSigno) { #ifdef _WIN32 // Restore handler as it is not persistent on Windows I think this concurrency fix for SIGINT would be better in a separate patch. I understand how it's related to the rest of this patch, but LLVM folks tend to prefer small, incremental patches. https://reviews.llvm.org/D37923 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37926: Fix the SIGINT handlers
clayborg added a comment. Looks fine to me. https://reviews.llvm.org/D37926 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37930: Use ThreadLauncher to launch TaskPool threads
fjricci created this revision. This allows for the stack size to be configured, which isn't possible with std::thread. Prevents overflowing the stack when performing complex operations in the task pool on darwin, where the default pthread stack size is only 512kb. https://reviews.llvm.org/D37930 Files: source/Utility/TaskPool.cpp Index: source/Utility/TaskPool.cpp === --- source/Utility/TaskPool.cpp +++ source/Utility/TaskPool.cpp @@ -8,6 +8,7 @@ //===--===// #include "lldb/Utility/TaskPool.h" +#include "lldb/Host/ThreadLauncher.h" #include // for uint32_t #include// for queue @@ -23,6 +24,8 @@ private: TaskPoolImpl(); + static lldb::thread_result_t WorkerPtr(void *pool); + static void Worker(TaskPoolImpl *pool); std::queue> m_tasks; @@ -54,10 +57,17 @@ // This prevents the thread // from exiting prematurely and triggering a linux libc bug // (https://sourceware.org/bugzilla/show_bug.cgi?id=19951). -std::thread(Worker, this).detach(); +lldb_private::ThreadLauncher::LaunchThread("task-pool.worker", WorkerPtr, + this, nullptr, 8 * 1024 * 1024) +.Release(); } } +lldb::thread_result_t TaskPoolImpl::WorkerPtr(void *pool) { + Worker((TaskPoolImpl *)pool); + return 0; +} + void TaskPoolImpl::Worker(TaskPoolImpl *pool) { while (true) { std::unique_lock lock(pool->m_tasks_mutex); Index: source/Utility/TaskPool.cpp === --- source/Utility/TaskPool.cpp +++ source/Utility/TaskPool.cpp @@ -8,6 +8,7 @@ //===--===// #include "lldb/Utility/TaskPool.h" +#include "lldb/Host/ThreadLauncher.h" #include // for uint32_t #include// for queue @@ -23,6 +24,8 @@ private: TaskPoolImpl(); + static lldb::thread_result_t WorkerPtr(void *pool); + static void Worker(TaskPoolImpl *pool); std::queue> m_tasks; @@ -54,10 +57,17 @@ // This prevents the thread // from exiting prematurely and triggering a linux libc bug // (https://sourceware.org/bugzilla/show_bug.cgi?id=19951). -std::thread(Worker, this).detach(); +lldb_private::ThreadLauncher::LaunchThread("task-pool.worker", WorkerPtr, + this, nullptr, 8 * 1024 * 1024) +.Release(); } } +lldb::thread_result_t TaskPoolImpl::WorkerPtr(void *pool) { + Worker((TaskPoolImpl *)pool); + return 0; +} + void TaskPoolImpl::Worker(TaskPoolImpl *pool) { while (true) { std::unique_lock lock(pool->m_tasks_mutex); ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37923: Implement interactive command interruption
lemo added inline comments. Comment at: source/Commands/CommandObjectTarget.cpp:2058 + break; +} num_dumped++; amccarth wrote: > Many LLVM developers prefer to omit the braces when the body of the > control-flow statement is a single statement. So do the hackers: https://blog.codecentric.de/en/2014/02/curly-braces :) I too prefer to omit braces in small test snippets, but in production code it's not worth the risk of making a silly mistake. Comment at: source/Interpreter/CommandInterpreter.cpp:2720 + chunk_size = stream.Write(data, chunk_size); + assert(size >= chunk_size); + data += chunk_size; amccarth wrote: > This assert should precede the line before it. Pedantically, it should be both before and after (and for ultimate paranoid mode, asserting that Write returns <= than the passed in value) But the asserts looks for the really nasty case where "size -= chunk_size" overflows. Comment at: tools/driver/Driver.cpp:1189 - exit(signo); + _exit(signo); } amccarth wrote: > Can you add a comment explaining why this uses `_exit` rather than `exit`? > It's not obvious to me. Explained in the SIGINT patch: exit() is not signal-safe (http://pubs.opengroup.org/onlinepubs/95399/functions/exit.html) Calling it from a signal handler can result in all kind of nasty issues, in particular exit() does call a lot of stuff, both runtime and user code (ex. atexit functions) Comment at: tools/lldb-mi/MIDriverMain.cpp:71 //-- void sigint_handler(int vSigno) { #ifdef _WIN32 // Restore handler as it is not persistent on Windows amccarth wrote: > I think this concurrency fix for SIGINT would be better in a separate patch. > I understand how it's related to the rest of this patch, but LLVM folks tend > to prefer small, incremental patches. Agreed, I already split this change into separate patches (I wasn't sure if people prefer to review two small changes vs a single one with more context) https://reviews.llvm.org/D37923 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37923: Implement interactive command interruption
clayborg added inline comments. Comment at: source/Commands/CommandObjectTarget.cpp:2056-2058 +if (m_interpreter.WasInterrupted()) { + break; +} Remove braces Comment at: source/Commands/CommandObjectTarget.cpp:2087-2089 +if (m_interpreter.WasInterrupted()) { + break; +} Remove braces Comment at: source/Commands/CommandObjectTarget.cpp:2155-2157 +if (m_interpreter.WasInterrupted()) { + break; +} Remove braces Comment at: source/Commands/CommandObjectTarget.cpp:2179-2181 + if (m_interpreter.WasInterrupted()) { +break; + } Remove braces Comment at: source/Commands/CommandObjectTarget.cpp:2254-2256 +if (m_interpreter.WasInterrupted()) { + break; +} Remove braces Comment at: source/Commands/CommandObjectTarget.cpp:2278-2280 + if (m_interpreter.WasInterrupted()) { +break; + } Remove braces Comment at: source/Commands/CommandObjectTarget.cpp:2348-2350 +if (m_interpreter.WasInterrupted()) { + break; +} Remove braces Comment at: source/Interpreter/CommandInterpreter.cpp:2682 + auto prev_state = m_command_state.exchange(CommandHandlingState::eInProgress); + assert(prev_state == CommandHandlingState::eIdle); +} lldb_assert Comment at: source/Interpreter/CommandInterpreter.cpp:2687 + auto prev_state = m_command_state.exchange(CommandHandlingState::eIdle); + assert(prev_state != CommandHandlingState::eIdle); +} lldb_assert Comment at: source/Interpreter/CommandInterpreter.cpp:2708-2710 +const char *data = str.data(); +size_t size = str.size(); +while (size > 0 && !WasInterrupted()) { Since we are using "llvm::StringRef" here, why not use its split functionality? Something like: ``` bool done = false; while (!done) { auto pair = str.split('\n'); auto len = pair.first.size(); done = pair.second.empty(); // Include newline if we are not done if (!done) ++len; stream.Write(pair.first.data(), } ``` This approach also avoids the issue amccarth mentioned below about not ending with a newline. It is also quite a bit simpler to follow. Comment at: source/Interpreter/CommandInterpreter.cpp:2728 + } else { +stream.PutCString(str); + } llvm::StringRef can contain NULLs right? Maybe use ``` stream.Write(data, size); ``` https://reviews.llvm.org/D37923 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37923: Implement interactive command interruption
lemo added inline comments. Comment at: source/Interpreter/CommandInterpreter.cpp:2713 + for (; chunk_size < size; ++chunk_size) { +assert(data[chunk_size] != '\0'); +if (data[chunk_size] == '\n') { amccarth wrote: > Should we be that trusting of a caller? In a non-debug build, if a caller > doesn't end the (non-empty) string with '\n', this'll just run past the end > of the buffer. Did I miss something that guarantees the caller won't make a > mistake? Would it be too expensive to play it safe? There's no assumption that the string ends with \n, see the loop condition: chunk_size < size. The assert is just to validate that we don't have embedded NULs. Comment at: source/Interpreter/CommandInterpreter.cpp:2708-2710 +const char *data = str.data(); +size_t size = str.size(); +while (size > 0 && !WasInterrupted()) { clayborg wrote: > Since we are using "llvm::StringRef" here, why not use its split > functionality? Something like: > ``` > bool done = false; > while (!done) { > auto pair = str.split('\n'); > auto len = pair.first.size(); > done = pair.second.empty(); > // Include newline if we are not done > if (!done) > ++len; > stream.Write(pair.first.data(), > } > ``` > > This approach also avoids the issue amccarth mentioned below about not ending > with a newline. It is also quite a bit simpler to follow. I'll give it a try, thanks for the suggestion. Comment at: source/Interpreter/CommandInterpreter.cpp:2728 + } else { +stream.PutCString(str); + } clayborg wrote: > llvm::StringRef can contain NULLs right? Maybe use > > ``` > stream.Write(data, size); > ``` The original code (line 2714) was using PutCString(), so this path is just preserving the original functionality (which also suggests that the output is not expected to have embedded nuls) https://reviews.llvm.org/D37923 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37934: Fix compatibility with OpenOCD debug stub.
vadimcn created this revision. vadimcn added a project: LLDB. OpenOCD sends register classes as two separate nodes, fixed parser to process both of them. OpenOCD returns "l" in response to "qfThreadInfo", so IsUnsupportedResponse() was false and we were ending up without any threads in the process. I think it's reasonable to assume that there's always at least one thread. Repository: rL LLVM https://reviews.llvm.org/D37934 Files: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp === --- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4168,7 +4168,6 @@ std::string osabi; stringVec includes; RegisterSetMap reg_set_map; - XMLNode feature_node; }; bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, @@ -4374,8 +4373,8 @@ XMLNode target_node = xml_document.GetRootElement("target"); if (target_node) { - XMLNode feature_node; - target_node.ForEachChildElement([&target_info, &feature_node]( + std::vector feature_nodes; + target_node.ForEachChildElement([&target_info, &feature_nodes]( const XMLNode &node) -> bool { llvm::StringRef name = node.GetName(); if (name == "architecture") { @@ -4387,7 +4386,7 @@ if (!href.empty()) target_info.includes.push_back(href.str()); } else if (name == "feature") { - feature_node = node; + feature_nodes.push_back(node); } else if (name == "groups") { node.ForEachChildElementWithName( "group", [&target_info](const XMLNode &node) -> bool { @@ -4423,7 +4422,7 @@ // set the Target's architecture yet, so the ABI is also potentially // incorrect. ABISP abi_to_use_sp = ABI::FindPlugin(shared_from_this(), arch_to_use); - if (feature_node) { + for (auto feature_node : feature_nodes) { ParseRegisters(feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset); } Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp === --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2624,8 +2624,7 @@ * tid. * Assume pid=tid=1 in such cases. */ -if (response.IsUnsupportedResponse() && thread_ids.size() == 0 && -IsConnected()) { +if (thread_ids.size() == 0 && IsConnected()) { thread_ids.push_back(1); } } else { Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp === --- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4168,7 +4168,6 @@ std::string osabi; stringVec includes; RegisterSetMap reg_set_map; - XMLNode feature_node; }; bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, @@ -4374,8 +4373,8 @@ XMLNode target_node = xml_document.GetRootElement("target"); if (target_node) { - XMLNode feature_node; - target_node.ForEachChildElement([&target_info, &feature_node]( + std::vector feature_nodes; + target_node.ForEachChildElement([&target_info, &feature_nodes]( const XMLNode &node) -> bool { llvm::StringRef name = node.GetName(); if (name == "architecture") { @@ -4387,7 +4386,7 @@ if (!href.empty()) target_info.includes.push_back(href.str()); } else if (name == "feature") { - feature_node = node; + feature_nodes.push_back(node); } else if (name == "groups") { node.ForEachChildElementWithName( "group", [&target_info](const XMLNode &node) -> bool { @@ -4423,7 +4422,7 @@ // set the Target's architecture yet, so the ABI is also potentially // incorrect. ABISP abi_to_use_sp = ABI::FindPlugin(shared_from_this(), arch_to_use); - if (feature_node) { + for (auto feature_node : feature_nodes) { ParseRegisters(feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset); } Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp === --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2624,8 +2624,7 @@ * tid. * Assume pid=tid=1 in such cases. */ -if (response.I
[Lldb-commits] [lldb] r313407 - Resubmit "[lit] Force site configs to run before source-tree configs"
Author: zturner Date: Fri Sep 15 15:10:46 2017 New Revision: 313407 URL: http://llvm.org/viewvc/llvm-project?rev=313407&view=rev Log: Resubmit "[lit] Force site configs to run before source-tree configs" This is a resubmission of r313270. It broke standalone builds of compiler-rt because we were not correctly generating the llvm-lit script in the standalone build directory. The fixes incorporated here attempt to find llvm/utils/llvm-lit from the source tree returned by llvm-config. If present, it will generate llvm-lit into the output directory. Regardless, the user can specify -DLLVM_EXTERNAL_LIT to point to a specific lit.py on their file system. This supports the use case of someone installing lit via a package manager. If it cannot find a source tree, and -DLLVM_EXTERNAL_LIT is either unspecified or invalid, then we print a warning that tests will not be able to run. Differential Revision: https://reviews.llvm.org/D37756 Modified: lldb/trunk/lit/Unit/lit.cfg lldb/trunk/lit/lit.cfg Modified: lldb/trunk/lit/Unit/lit.cfg URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Unit/lit.cfg?rev=313407&r1=313406&r2=313407&view=diff == --- lldb/trunk/lit/Unit/lit.cfg (original) +++ lldb/trunk/lit/Unit/lit.cfg Fri Sep 15 15:10:46 2017 @@ -6,19 +6,6 @@ import os import lit.formats -# Check that the object root is known. -if config.test_exec_root is None: -# Otherwise, we haven't loaded the site specific configuration (the user is -# probably trying to run on a test file directly, and either the site -# configuration hasn't been created by the build system, or we are in an -# out-of-tree build situation). - -# Check for 'llvm_unit_site_config' user parameter, and use that if available. -site_cfg = lit_config.params.get('lldb_unit_site_config', None) -if site_cfg and os.path.exists(site_cfg): -lit_config.load_config(config, site_cfg) -raise SystemExit - # name: The name of this test suite. config.name = 'lldb-Unit' @@ -31,6 +18,4 @@ config.test_source_root = os.path.join(c config.test_exec_root = config.test_source_root # testFormat: The test format to use to interpret tests. -if not hasattr(config, 'llvm_build_mode'): -lit_config.fatal("unable to find llvm_build_mode value on config") config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, 'Tests') Modified: lldb/trunk/lit/lit.cfg URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/lit.cfg?rev=313407&r1=313406&r2=313407&view=diff == --- lldb/trunk/lit/lit.cfg (original) +++ lldb/trunk/lit/lit.cfg Fri Sep 15 15:10:46 2017 @@ -29,94 +29,24 @@ config.suffixes = [] config.test_source_root = os.path.dirname(__file__) # test_exec_root: The root path where tests should be run. -lldb_obj_root = getattr(config, 'lldb_obj_root', None) -if lldb_obj_root is not None: -config.test_exec_root = os.path.join(lldb_obj_root, 'lit') - -# Set llvm_{src,obj}_root for use by others. -config.llvm_src_root = getattr(config, 'llvm_src_root', None) -config.llvm_obj_root = getattr(config, 'llvm_obj_root', None) +config.test_exec_root = os.path.join(config.lldb_obj_root, 'lit') # Tweak the PATH to include the tools dir and the scripts dir. -if lldb_obj_root is not None: -lldb_tools_dir = getattr(config, 'lldb_tools_dir', None) -if not lldb_tools_dir: -lit_config.fatal('No LLDB tools dir set!') -llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) -if not llvm_tools_dir: -lit_config.fatal('No LLVM tools dir set!') -path = os.path.pathsep.join((lldb_tools_dir, llvm_tools_dir, config.environment['PATH'])) -path = os.path.pathsep.join((os.path.join(getattr(config, 'llvm_src_root', None),'test','Scripts'),path)) - -config.environment['PATH'] = path - -lldb_libs_dir = getattr(config, 'lldb_libs_dir', None) -if not lldb_libs_dir: -lit_config.fatal('No LLDB libs dir set!') -llvm_libs_dir = getattr(config, 'llvm_libs_dir', None) -if not llvm_libs_dir: -lit_config.fatal('No LLVM libs dir set!') -path = os.path.pathsep.join((lldb_libs_dir, llvm_libs_dir, - config.environment.get('LD_LIBRARY_PATH',''))) -config.environment['LD_LIBRARY_PATH'] = path - -# Propagate LLVM_SRC_ROOT into the environment. -config.environment['LLVM_SRC_ROOT'] = getattr(config, 'llvm_src_root', '') - -# Propagate PYTHON_EXECUTABLE into the environment -config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable', - '') -### - -# Check that the object root is known. -if config.test_exec_root is None: -# Otherwise, we haven't loaded the site specific configuration (the user is -# probably trying to run on a test file directly, and either the site -# con
[Lldb-commits] [PATCH] D37934: Fix compatibility with OpenOCD debug stub.
clayborg added a comment. The multiple feature fix is fine. As for the qfThreadInfo fix, do you not have control over the OpenOCD GDB server? I would be nice to modify it to return something valid in response to qfThreadInfo? If you don't control or have access to modify the OpenOCD GDB server, we should at least verify that you sent qfThreadInfo and got "l" as the only response. Seems weird to say we will accept any kind of input. Repository: rL LLVM https://reviews.llvm.org/D37934 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37923: Implement interactive command interruption
lemo updated this revision to Diff 115516. lemo edited the summary of this revision. lemo added a comment. Incorporating CR feedback. https://reviews.llvm.org/D37923 Files: include/lldb/Core/IOHandler.h include/lldb/Interpreter/CommandInterpreter.h source/Commands/CommandObjectTarget.cpp source/Interpreter/CommandInterpreter.cpp Index: source/Interpreter/CommandInterpreter.cpp === --- source/Interpreter/CommandInterpreter.cpp +++ source/Interpreter/CommandInterpreter.cpp @@ -546,7 +546,7 @@ char buffer[1024]; int num_printed = snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o"); - assert(num_printed < 1024); + lldbassert(num_printed < 1024); UNUSED_IF_ASSERT_DISABLED(num_printed); success = tbreak_regex_cmd_ap->AddRegexCommand(break_regexes[i][0], buffer); @@ -891,7 +891,7 @@ const lldb::CommandObjectSP &cmd_sp, bool can_replace) { if (cmd_sp.get()) -assert((this == &cmd_sp->GetCommandInterpreter()) && +lldbassert((this == &cmd_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter"); if (name.empty()) @@ -913,7 +913,7 @@ const lldb::CommandObjectSP &cmd_sp, bool can_replace) { if (cmd_sp.get()) -assert((this == &cmd_sp->GetCommandInterpreter()) && +lldbassert((this == &cmd_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter"); if (!name.empty()) { @@ -1062,7 +1062,7 @@ lldb::CommandObjectSP &command_obj_sp, llvm::StringRef args_string) { if (command_obj_sp.get()) -assert((this == &command_obj_sp->GetCommandInterpreter()) && +lldbassert((this == &command_obj_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter"); std::unique_ptr command_alias_up( @@ -1839,7 +1839,7 @@ matches.Clear(); // Only max_return_elements == -1 is supported at present: - assert(max_return_elements == -1); + lldbassert(max_return_elements == -1); bool word_complete; num_command_matches = HandleCompletionMatches( parsed_line, cursor_index, cursor_char_position, match_start_point, @@ -2677,6 +2677,57 @@ return total_bytes; } +void CommandInterpreter::StartHandlingCommand() { + auto prev_state = m_command_state.exchange(CommandHandlingState::eInProgress); + lldbassert(prev_state == CommandHandlingState::eIdle); +} + +void CommandInterpreter::FinishHandlingCommand() { + auto prev_state = m_command_state.exchange(CommandHandlingState::eIdle); + lldbassert(prev_state != CommandHandlingState::eIdle); +} + +bool CommandInterpreter::InterruptCommand() { + auto in_progress = CommandHandlingState::eInProgress; + return m_command_state.compare_exchange_strong( + in_progress, CommandHandlingState::eInterrupted); +} + +bool CommandInterpreter::WasInterrupted() const { + return m_command_state == CommandHandlingState::eInterrupted; +} + +void CommandInterpreter::PrintCommandOutput(Stream &stream, llvm::StringRef str, +bool interruptible) { + if (str.empty()) +return; + + if (interruptible) { +// Split the output into lines and poll for interrupt requests +const char *data = str.data(); +size_t size = str.size(); +while (size > 0 && !WasInterrupted()) { + size_t chunk_size = 0; + for (; chunk_size < size; ++chunk_size) { +lldbassert(data[chunk_size] != '\0'); +if (data[chunk_size] == '\n') { + ++chunk_size; + break; +} + } + chunk_size = stream.Write(data, chunk_size); + lldbassert(size >= chunk_size); + data += chunk_size; + size -= chunk_size; +} +if (size > 0) { + stream.Printf("\n... Interrupted.\n"); +} + } else { +stream.PutCString(str); + } +} + void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, std::string &line) { const bool is_interactive = io_handler.GetIsInteractive(); @@ -2700,6 +2751,8 @@ line.c_str()); } + StartHandlingCommand(); + lldb_private::CommandReturnObject result; HandleCommand(line.c_str(), eLazyBoolCalculate, result); @@ -2710,18 +2763,20 @@ if (!result.GetImmediateOutputStream()) { llvm::StringRef output = result.GetOutputData(); - if (!output.empty()) -io_handler.GetOutputStreamFile()->PutCString(output); + PrintCommandOutput(*io_handler.GetOutputStreamFile(), output, + is_interactive); } // Now emit the command error text from the command we just executed if (!result.
[Lldb-commits] [PATCH] D37934: Fix compatibility with OpenOCD debug stub.
vadimcn added a comment. This is what I see in the log: < 16> send packet: $qfThreadInfo#bb < 5> read packet: $l#6c And here's code that generates it: https://github.com/gnu-mcu-eclipse/openocd/blob/b21ab1d683aaee501d45fe8a509a2043123f16fd/src/rtos/rtos.c#L370 I agree, they should have responded with "not supported", but I've never heard of a system that allows processes without threads, and openocd is pretty popular in embedded, so I think it would make sense to just support this quirk. That's what gdb does anyways... Repository: rL LLVM https://reviews.llvm.org/D37934 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D37934: Fix compatibility with OpenOCD debug stub.
clayborg accepted this revision. clayborg added a comment. This revision is now accepted and ready to land. As long as everyone agrees that no threads from qfThreadInfo means there is one thread whose thread ID is 1 then this is ok. Repository: rL LLVM https://reviews.llvm.org/D37934 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] r313436 - More precise c library feature detection for Android.
Author: eugene Date: Fri Sep 15 19:19:21 2017 New Revision: 313436 URL: http://llvm.org/viewvc/llvm-project?rev=313436&view=rev Log: More precise c library feature detection for Android. Modified: lldb/trunk/cmake/modules/LLDBGenerateConfig.cmake lldb/trunk/source/Host/common/Socket.cpp lldb/trunk/source/Host/posix/ProcessLauncherPosixFork.cpp Modified: lldb/trunk/cmake/modules/LLDBGenerateConfig.cmake URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/cmake/modules/LLDBGenerateConfig.cmake?rev=313436&r1=313435&r2=313436&view=diff == --- lldb/trunk/cmake/modules/LLDBGenerateConfig.cmake (original) +++ lldb/trunk/cmake/modules/LLDBGenerateConfig.cmake Fri Sep 15 19:19:21 2017 @@ -9,6 +9,7 @@ set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SO check_symbol_exists(ppoll poll.h HAVE_PPOLL) set(CMAKE_REQUIRED_DEFINITIONS) check_symbol_exists(sigaction signal.h HAVE_SIGACTION) +check_symbol_exists(accept4 "sys/socket.h" HAVE_ACCEPT4) check_include_file(termios.h HAVE_TERMIOS_H) check_include_files("sys/types.h;sys/event.h" HAVE_SYS_EVENT_H) Modified: lldb/trunk/source/Host/common/Socket.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Socket.cpp?rev=313436&r1=313435&r2=313436&view=diff == --- lldb/trunk/source/Host/common/Socket.cpp (original) +++ lldb/trunk/source/Host/common/Socket.cpp Fri Sep 15 19:19:21 2017 @@ -450,7 +450,7 @@ NativeSocket Socket::AcceptSocket(Native close(fd); } return fd; -#elif defined(SOCK_CLOEXEC) +#elif defined(SOCK_CLOEXEC) && defined(HAVE_ACCEPT4) int flags = 0; if (!child_processes_inherit) { flags |= SOCK_CLOEXEC; Modified: lldb/trunk/source/Host/posix/ProcessLauncherPosixFork.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/ProcessLauncherPosixFork.cpp?rev=313436&r1=313435&r2=313436&view=diff == --- lldb/trunk/source/Host/posix/ProcessLauncherPosixFork.cpp (original) +++ lldb/trunk/source/Host/posix/ProcessLauncherPosixFork.cpp Fri Sep 15 19:19:21 2017 @@ -29,7 +29,7 @@ #define PT_TRACE_ME PTRACE_TRACEME #endif -#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 +#if defined(__ANDROID_API__) && __ANDROID_API__ < 15 #include #elif defined(__linux__) #include ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] r313437 - Check availability of accept4 in C++ instad of C code.
Author: eugene Date: Fri Sep 15 19:58:49 2017 New Revision: 313437 URL: http://llvm.org/viewvc/llvm-project?rev=313437&view=rev Log: Check availability of accept4 in C++ instad of C code. Modified: lldb/trunk/cmake/modules/LLDBGenerateConfig.cmake Modified: lldb/trunk/cmake/modules/LLDBGenerateConfig.cmake URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/cmake/modules/LLDBGenerateConfig.cmake?rev=313437&r1=313436&r2=313437&view=diff == --- lldb/trunk/cmake/modules/LLDBGenerateConfig.cmake (original) +++ lldb/trunk/cmake/modules/LLDBGenerateConfig.cmake Fri Sep 15 19:58:49 2017 @@ -9,7 +9,7 @@ set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SO check_symbol_exists(ppoll poll.h HAVE_PPOLL) set(CMAKE_REQUIRED_DEFINITIONS) check_symbol_exists(sigaction signal.h HAVE_SIGACTION) -check_symbol_exists(accept4 "sys/socket.h" HAVE_ACCEPT4) +check_cxx_symbol_exists(accept4 "sys/socket.h" HAVE_ACCEPT4) check_include_file(termios.h HAVE_TERMIOS_H) check_include_files("sys/types.h;sys/event.h" HAVE_SYS_EVENT_H) ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] r313442 - Fix compatibility with OpenOCD debug stub.
Author: vadimcn Date: Fri Sep 15 20:53:13 2017 New Revision: 313442 URL: http://llvm.org/viewvc/llvm-project?rev=313442&view=rev Log: Fix compatibility with OpenOCD debug stub. OpenOCD sends register classes as two separate nodes, fixed parser to process both of them. OpenOCD returns "l" in response to "qfThreadInfo", so IsUnsupportedResponse() was false and we were ending up without any threads in the process. I think it's reasonable to assume that there's always at least one thread. Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.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=313442&r1=313441&r2=313442&view=diff == --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Fri Sep 15 20:53:13 2017 @@ -2624,8 +2624,7 @@ size_t GDBRemoteCommunicationClient::Get * tid. * Assume pid=tid=1 in such cases. */ -if (response.IsUnsupportedResponse() && thread_ids.size() == 0 && -IsConnected()) { +if (thread_ids.size() == 0 && IsConnected()) { thread_ids.push_back(1); } } else { Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=313442&r1=313441&r2=313442&view=diff == --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Sep 15 20:53:13 2017 @@ -4168,7 +4168,6 @@ struct GdbServerTargetInfo { std::string osabi; stringVec includes; RegisterSetMap reg_set_map; - XMLNode feature_node; }; bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, @@ -4374,8 +4373,8 @@ bool ProcessGDBRemote::GetGDBServerRegis XMLNode target_node = xml_document.GetRootElement("target"); if (target_node) { - XMLNode feature_node; - target_node.ForEachChildElement([&target_info, &feature_node]( + std::vector feature_nodes; + target_node.ForEachChildElement([&target_info, &feature_nodes]( const XMLNode &node) -> bool { llvm::StringRef name = node.GetName(); if (name == "architecture") { @@ -4387,7 +4386,7 @@ bool ProcessGDBRemote::GetGDBServerRegis if (!href.empty()) target_info.includes.push_back(href.str()); } else if (name == "feature") { - feature_node = node; + feature_nodes.push_back(node); } else if (name == "groups") { node.ForEachChildElementWithName( "group", [&target_info](const XMLNode &node) -> bool { @@ -4423,7 +4422,7 @@ bool ProcessGDBRemote::GetGDBServerRegis // set the Target's architecture yet, so the ABI is also potentially // incorrect. ABISP abi_to_use_sp = ABI::FindPlugin(shared_from_this(), arch_to_use); - if (feature_node) { + for (auto &feature_node : feature_nodes) { ParseRegisters(feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset); } ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits