From 9bdea541cab4e540dc9c8d88edcb9c23f75d9595 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Fri, 6 Feb 2015 02:10:56 +0000 Subject: Add a "-a/--address" option to "thread until". You can specify one or more line numbers (as arguments) and/or one or more addresses (with -a) and until will stop at the first one of thesepoints it hits, or on exit from the function if you leave the function before hitting any of these stop points. llvm-svn: 228370 --- lldb/source/Commands/CommandObjectThread.cpp | 88 +++++++++++++++++++--------- 1 file changed, 61 insertions(+), 27 deletions(-) (limited to 'lldb/source/Commands/CommandObjectThread.cpp') diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index 3789164..199d16b 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -985,6 +985,14 @@ public: switch (short_option) { + case 'a': + { + ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); + lldb::addr_t tmp_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); + if (error.Success()) + m_until_addrs.push_back(tmp_addr); + } + break; case 't': { m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32); @@ -1031,6 +1039,7 @@ public: m_thread_idx = LLDB_INVALID_THREAD_ID; m_frame_idx = 0; m_stop_others = false; + m_until_addrs.clear(); } const OptionDefinition* @@ -1041,6 +1050,7 @@ public: uint32_t m_step_thread_idx; bool m_stop_others; + std::vector m_until_addrs; // Options table: Required for subclasses of Options. @@ -1052,7 +1062,7 @@ public: CommandObjectThreadUntil (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, "thread until", - "Run the current or specified thread until it reaches a given line number or leaves the current function.", + "Run the current or specified thread until it reaches a given line number or address or leaves the current function.", NULL, eFlagRequiresThread | eFlagTryTargetAPILock | @@ -1111,23 +1121,33 @@ protected: else { Thread *thread = NULL; - uint32_t line_number; + std::vector line_numbers; - if (command.GetArgumentCount() != 1) + if (command.GetArgumentCount() >= 1) { - result.AppendErrorWithFormat ("No line number provided:\n%s", GetSyntax()); - result.SetStatus (eReturnStatusFailed); - return false; + size_t num_args = command.GetArgumentCount(); + for (size_t i = 0; i < num_args; i++) + { + uint32_t line_number; + line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX); + if (line_number == UINT32_MAX) + { + result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0)); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + line_numbers.push_back(line_number); + } } - - line_number = StringConvert::ToUInt32 (command.GetArgumentAtIndex(0), UINT32_MAX); - if (line_number == UINT32_MAX) + else if (m_options.m_until_addrs.empty()) { - result.AppendErrorWithFormat ("invalid line number: '%s'.\n", command.GetArgumentAtIndex(0)); + result.AppendErrorWithFormat ("No line number or address provided:\n%s", GetSyntax()); result.SetStatus (eReturnStatusFailed); return false; } + if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) { thread = process->GetThreadList().GetSelectedThread().get(); @@ -1189,27 +1209,40 @@ protected: Address fun_end_addr(fun_start_addr.GetSection(), fun_start_addr.GetOffset() + fun_addr_range.GetByteSize()); - line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr); bool all_in_function = true; - - while (index_ptr <= end_ptr) + + line_table->FindLineEntryByAddress (fun_end_addr, function_start, &end_ptr); + + for (uint32_t line_number : line_numbers) { - LineEntry line_entry; - const bool exact = false; - index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry); - if (index_ptr == UINT32_MAX) - break; - - addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); - if (address != LLDB_INVALID_ADDRESS) + uint32_t start_idx_ptr = index_ptr; + while (start_idx_ptr <= end_ptr) { - if (fun_addr_range.ContainsLoadAddress (address, target)) - address_list.push_back (address); - else - all_in_function = false; + LineEntry line_entry; + const bool exact = false; + start_idx_ptr = sc.comp_unit->FindLineEntry(start_idx_ptr, line_number, sc.comp_unit, exact, &line_entry); + if (start_idx_ptr == UINT32_MAX) + break; + + addr_t address = line_entry.range.GetBaseAddress().GetLoadAddress(target); + if (address != LLDB_INVALID_ADDRESS) + { + if (fun_addr_range.ContainsLoadAddress (address, target)) + address_list.push_back (address); + else + all_in_function = false; + } + start_idx_ptr++; } - index_ptr++; + } + + for (lldb::addr_t address : m_options.m_until_addrs) + { + if (fun_addr_range.ContainsLoadAddress (address, target)) + address_list.push_back (address); + else + all_in_function = false; } if (address_list.size() == 0) @@ -1291,7 +1324,8 @@ CommandObjectThreadUntil::CommandOptions::g_option_table[] = { { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, -{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode,"Determine how to run other threads while stepping this one"}, +{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, NULL, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one"}, +{ LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."}, { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; -- cgit v1.1