diff options
author | dim <dim@FreeBSD.org> | 2016-12-26 20:36:37 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2016-12-26 20:36:37 +0000 |
commit | 06210ae42d418d50d8d9365d5c9419308ae9e7ee (patch) | |
tree | ab60b4cdd6e430dda1f292a46a77ddb744723f31 /contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp | |
parent | 2dd166267f53df1c3748b4325d294b9b839de74b (diff) | |
download | FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.zip FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.tar.gz |
MFC r309124:
Upgrade our copies of clang, llvm, lldb, compiler-rt and libc++ to 3.9.0
release, and add lld 3.9.0. Also completely revamp the build system for
clang, llvm, lldb and their related tools.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Release notes for llvm, clang and lld are available here:
<http://llvm.org/releases/3.9.0/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.9.0/tools/clang/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.9.0/tools/lld/docs/ReleaseNotes.html>
Thanks to Ed Maste, Bryan Drewery, Andrew Turner, Antoine Brodin and Jan
Beich for their help.
Relnotes: yes
MFC r309147:
Pull in r282174 from upstream llvm trunk (by Krzysztof Parzyszek):
[PPC] Set SP after loading data from stack frame, if no red zone is
present
Follow-up to r280705: Make sure that the SP is only restored after
all data is loaded from the stack frame, if there is no red zone.
This completes the fix for
https://llvm.org/bugs/show_bug.cgi?id=26519.
Differential Revision: https://reviews.llvm.org/D24466
Reported by: Mark Millard
PR: 214433
MFC r309149:
Pull in r283060 from upstream llvm trunk (by Hal Finkel):
[PowerPC] Refactor soft-float support, and enable PPC64 soft float
This change enables soft-float for PowerPC64, and also makes
soft-float disable all vector instruction sets for both 32-bit and
64-bit modes. This latter part is necessary because the PPC backend
canonicalizes many Altivec vector types to floating-point types, and
so soft-float breaks scalarization support for many operations. Both
for embedded targets and for operating-system kernels desiring
soft-float support, it seems reasonable that disabling hardware
floating-point also disables vector instructions (embedded targets
without hardware floating point support are unlikely to have Altivec,
etc. and operating system kernels desiring not to use floating-point
registers to lower syscall cost are unlikely to want to use vector
registers either). If someone needs this to work, we'll need to
change the fact that we promote many Altivec operations to act on
v4f32. To make it possible to disable Altivec when soft-float is
enabled, hardware floating-point support needs to be expressed as a
positive feature, like the others, and not a negative feature,
because target features cannot have dependencies on the disabling of
some other feature. So +soft-float has now become -hard-float.
Fixes PR26970.
Pull in r283061 from upstream clang trunk (by Hal Finkel):
[PowerPC] Enable soft-float for PPC64, and +soft-float -> -hard-float
Enable soft-float support on PPC64, as the backend now supports it.
Also, the backend now uses -hard-float instead of +soft-float, so set
the target features accordingly.
Fixes PR26970.
Reported by: Mark Millard
PR: 214433
MFC r309212:
Add a few missed clang 3.9.0 files to OptionalObsoleteFiles.
MFC r309262:
Fix packaging for clang, lldb and lld 3.9.0
During the upgrade of clang/llvm etc to 3.9.0 in r309124, the PACKAGE
directive in the usr.bin/clang/*.mk files got dropped accidentally.
Restore it, with a few minor changes and additions:
* Correct license in clang.ucl to NCSA
* Add PACKAGE=clang for clang and most of the "ll" tools
* Put lldb in its own package
* Put lld in its own package
Reviewed by: gjb, jmallett
Differential Revision: https://reviews.freebsd.org/D8666
MFC r309656:
During the bootstrap phase, when building the minimal llvm library on
PowerPC, add lib/Support/Atomic.cpp. This is needed because upstream
llvm revision r271821 disabled the use of std::call_once, which causes
some fallback functions from Atomic.cpp to be used instead.
Reported by: Mark Millard
PR: 214902
MFC r309835:
Tentatively apply https://reviews.llvm.org/D18730 to work around gcc PR
70528 (bogus error: constructor required before non-static data member).
This should fix buildworld with the external gcc package.
Reported by: https://jenkins.freebsd.org/job/FreeBSD_HEAD_amd64_gcc/
MFC r310194:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
3.9.1 release.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Release notes for llvm, clang and lld will be available here:
<http://releases.llvm.org/3.9.1/docs/ReleaseNotes.html>
<http://releases.llvm.org/3.9.1/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/3.9.1/tools/lld/docs/ReleaseNotes.html>
Relnotes: yes
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp | 802 |
1 files changed, 377 insertions, 425 deletions
diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp index e932c9d..9e4bffd 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp @@ -37,11 +37,9 @@ #include "lldb/Target/ThreadPlanStepRange.h" #include "lldb/Target/ThreadPlanStepInRange.h" - using namespace lldb; using namespace lldb_private; - //------------------------------------------------------------------------- // CommandObjectThreadBacktrace //------------------------------------------------------------------------- @@ -58,7 +56,7 @@ public: { } - ~CommandObjectIterateOverThreads() override {} + ~CommandObjectIterateOverThreads() override = default; bool DoExecute (Args& command, CommandReturnObject &result) override @@ -68,34 +66,33 @@ public: if (command.GetArgumentCount() == 0) { Thread *thread = m_exe_ctx.GetThreadPtr(); - if (!HandleOneThread (*thread, result)) + if (!HandleOneThread (thread->GetID(), result)) return false; + return result.Succeeded(); } - else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0) + + // Use tids instead of ThreadSPs to prevent deadlocking problems which result from JIT-ing + // code while iterating over the (locked) ThreadSP list. + std::vector<lldb::tid_t> tids; + + if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0) { Process *process = m_exe_ctx.GetProcessPtr(); - uint32_t idx = 0; - for (ThreadSP thread_sp : process->Threads()) - { - if (idx != 0 && m_add_return) - result.AppendMessage(""); - if (!HandleOneThread(*(thread_sp.get()), result)) - return false; - ++idx; - } + for (ThreadSP thread_sp : process->Threads()) + tids.push_back(thread_sp->GetID()); } else { const size_t num_args = command.GetArgumentCount(); Process *process = m_exe_ctx.GetProcessPtr(); - Mutex::Locker locker (process->GetThreadList().GetMutex()); - std::vector<ThreadSP> thread_sps; + + std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex()); for (size_t i = 0; i < num_args; i++) { bool success; - + uint32_t thread_idx = StringConvert::ToUInt32(command.GetArgumentAtIndex(i), 0, 0, &success); if (!success) { @@ -103,32 +100,35 @@ public: result.SetStatus (eReturnStatusFailed); return false; } - - thread_sps.push_back(process->GetThreadList().FindThreadByIndexID(thread_idx)); - - if (!thread_sps[i]) + + ThreadSP thread = process->GetThreadList().FindThreadByIndexID(thread_idx); + + if (!thread) { result.AppendErrorWithFormat ("no thread with index: \"%s\"\n", command.GetArgumentAtIndex(i)); result.SetStatus (eReturnStatusFailed); return false; } - - } - - for (uint32_t i = 0; i < num_args; i++) - { - if (!HandleOneThread (*(thread_sps[i].get()), result)) - return false; - if (i < num_args - 1 && m_add_return) - result.AppendMessage(""); + tids.push_back(thread->GetID()); } } + + uint32_t idx = 0; + for (const lldb::tid_t &tid : tids) + { + if (idx != 0 && m_add_return) + result.AppendMessage(""); + + if (!HandleOneThread (tid, result)) + return false; + + ++idx; + } return result.Succeeded(); } protected: - // Override this to do whatever you need to do for one thread. // // If you return false, the iteration will stop, otherwise it will proceed. @@ -137,11 +137,10 @@ protected: // If m_add_return is true, a blank line will be inserted between each of the listings (except the last one.) virtual bool - HandleOneThread (Thread &thread, CommandReturnObject &result) = 0; + HandleOneThread (lldb::tid_t, CommandReturnObject &result) = 0; ReturnStatus m_success_return = eReturnStatusSuccessFinishResult; bool m_add_return = true; - }; //------------------------------------------------------------------------- @@ -151,11 +150,9 @@ protected: class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads { public: - class CommandOptions : public Options { public: - CommandOptions (CommandInterpreter &interpreter) : Options(interpreter) { @@ -163,9 +160,7 @@ public: OptionParsingStarting (); } - ~CommandOptions () override - { - } + ~CommandOptions() override = default; Error SetOptionValue (uint32_t option_idx, const char *option_arg) override @@ -194,6 +189,7 @@ public: if (!success) error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option); } + break; case 'e': { bool success; @@ -205,7 +201,6 @@ public: default: error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); break; - } return error; } @@ -234,23 +229,18 @@ public: bool m_extended_backtrace; }; - CommandObjectThreadBacktrace (CommandInterpreter &interpreter) : - CommandObjectIterateOverThreads (interpreter, - "thread backtrace", - "Show the stack for one or more threads. If no threads are specified, show the currently selected thread. Use the thread-index \"all\" to see all threads.", - NULL, - eCommandRequiresProcess | - eCommandRequiresThread | - eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused ), - m_options(interpreter) + CommandObjectThreadBacktrace(CommandInterpreter &interpreter) + : CommandObjectIterateOverThreads( + interpreter, "thread backtrace", "Show thread call stacks. Defaults to the current thread, thread " + "indexes can be specified as arguments. Use the thread-index \"all\" " + "to see all threads.", + nullptr, eCommandRequiresProcess | eCommandRequiresThread | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), + m_options(interpreter) { } - ~CommandObjectThreadBacktrace() override - { - } + ~CommandObjectThreadBacktrace() override = default; Options * GetOptions () override @@ -286,25 +276,35 @@ protected: } bool - HandleOneThread (Thread &thread, CommandReturnObject &result) override + HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override { + ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); + if (!thread_sp) + { + result.AppendErrorWithFormat ("thread disappeared while computing backtraces: 0x%" PRIx64 "\n", tid); + result.SetStatus (eReturnStatusFailed); + return false; + } + + Thread *thread = thread_sp.get(); + Stream &strm = result.GetOutputStream(); // Don't show source context when doing backtraces. const uint32_t num_frames_with_source = 0; - if (!thread.GetStatus (strm, - m_options.m_start, - m_options.m_count, - num_frames_with_source)) + if (!thread->GetStatus (strm, + m_options.m_start, + m_options.m_count, + num_frames_with_source)) { - result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread.GetIndexID()); + result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", thread->GetIndexID()); result.SetStatus (eReturnStatusFailed); return false; } if (m_options.m_extended_backtrace) { - DoExtendedBacktrace (&thread, result); + DoExtendedBacktrace (thread, result); } return true; @@ -316,10 +316,10 @@ protected: OptionDefinition CommandObjectThreadBacktrace::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"}, -{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"}, -{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"}, -{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many frames to display (-1 for all)"}, +{ LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"}, +{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show the extended backtrace, if available"}, +{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } }; enum StepScope @@ -331,11 +331,9 @@ enum StepScope class CommandObjectThreadStepWithTypeAndScope : public CommandObjectParsed { public: - class CommandOptions : public Options { public: - CommandOptions (CommandInterpreter &interpreter) : Options (interpreter) { @@ -343,9 +341,7 @@ public: OptionParsingStarting (); } - ~CommandOptions () override - { - } + ~CommandOptions() override = default; Error SetOptionValue (uint32_t option_idx, const char *option_arg) override @@ -382,19 +378,16 @@ public: break; case 'c': - { - m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); - if (m_step_count == UINT32_MAX) - error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg); - break; - } + m_step_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); + if (m_step_count == UINT32_MAX) + error.SetErrorStringWithFormat ("invalid step count '%s'", option_arg); break; + case 'C': - { - m_class_name.clear(); - m_class_name.assign(option_arg); - } + m_class_name.clear(); + m_class_name.assign(option_arg); break; + case 'm': { OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; @@ -402,24 +395,35 @@ public: } break; - case 'r': + case 'e': { - m_avoid_regexp.clear(); - m_avoid_regexp.assign(option_arg); + if (strcmp(option_arg, "block") == 0) + { + m_end_line_is_block_end = 1; + break; + } + uint32_t tmp_end_line = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); + if (tmp_end_line == UINT32_MAX) + error.SetErrorStringWithFormat ("invalid end line number '%s'", option_arg); + else + m_end_line = tmp_end_line; + break; } break; - case 't': - { - m_step_in_target.clear(); - m_step_in_target.assign(option_arg); + case 'r': + m_avoid_regexp.clear(); + m_avoid_regexp.assign(option_arg); + break; - } + case 't': + m_step_in_target.clear(); + m_step_in_target.assign(option_arg); break; + default: error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); break; - } return error; } @@ -433,13 +437,15 @@ public: // Check if we are in Non-Stop mode lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget(); - if (target_sp.get() != nullptr && target_sp->GetNonStopModeEnabled()) + if (target_sp && target_sp->GetNonStopModeEnabled()) m_run_mode = eOnlyThisThread; m_avoid_regexp.clear(); m_step_in_target.clear(); m_class_name.clear(); m_step_count = 1; + m_end_line = LLDB_INVALID_LINE_NUMBER; + m_end_line_is_block_end = false; } const OptionDefinition* @@ -460,6 +466,8 @@ public: std::string m_step_in_target; std::string m_class_name; uint32_t m_step_count; + uint32_t m_end_line; + bool m_end_line_is_block_end; }; CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter, @@ -492,9 +500,7 @@ public: m_arguments.push_back (arg); } - ~CommandObjectThreadStepWithTypeAndScope () override - { - } + ~CommandObjectThreadStepWithTypeAndScope() override = default; Options * GetOptions () override @@ -510,12 +516,13 @@ protected: bool synchronous_execution = m_interpreter.GetSynchronous(); const uint32_t num_threads = process->GetThreadList().GetSize(); - Thread *thread = NULL; + Thread *thread = nullptr; if (command.GetArgumentCount() == 0) { - thread = process->GetThreadList().GetSelectedThread().get(); - if (thread == NULL) + thread = GetDefaultThread(); + + if (thread == nullptr) { result.AppendError ("no selected thread in process"); result.SetStatus (eReturnStatusFailed); @@ -533,7 +540,7 @@ protected: return false; } thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get(); - if (thread == NULL) + if (thread == nullptr) { result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", step_thread_idx, num_threads); @@ -558,6 +565,14 @@ protected: } } + if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER + && m_step_type != eStepTypeInto) + { + result.AppendErrorWithFormat("end line option is only valid for step into"); + result.SetStatus(eReturnStatusFailed); + return false; + } + const bool abort_other_plans = false; const lldb::RunMode stop_other_threads = m_options.m_run_mode; @@ -567,12 +582,7 @@ protected: if (m_options.m_run_mode == eAllThreads) bool_stop_other_threads = false; else if (m_options.m_run_mode == eOnlyDuringStepping) - { - if (m_step_type == eStepTypeOut || m_step_type == eStepTypeScripted) - bool_stop_other_threads = false; - else - bool_stop_other_threads = true; - } + bool_stop_other_threads = (m_step_type != eStepTypeOut && m_step_type != eStepTypeScripted); else bool_stop_other_threads = true; @@ -585,13 +595,54 @@ protected: if (frame->HasDebugInformation ()) { + AddressRange range; + SymbolContext sc = frame->GetSymbolContext(eSymbolContextEverything); + if (m_options.m_end_line != LLDB_INVALID_LINE_NUMBER) + { + Error error; + if (!sc.GetAddressRangeFromHereToEndLine(m_options.m_end_line, range, error)) + { + result.AppendErrorWithFormat("invalid end-line option: %s.", error.AsCString()); + result.SetStatus(eReturnStatusFailed); + return false; + } + } + else if (m_options.m_end_line_is_block_end) + { + Error error; + Block *block = frame->GetSymbolContext(eSymbolContextBlock).block; + if (!block) + { + result.AppendErrorWithFormat("Could not find the current block."); + result.SetStatus(eReturnStatusFailed); + return false; + } + + AddressRange block_range; + Address pc_address = frame->GetFrameCodeAddress(); + block->GetRangeContainingAddress(pc_address, block_range); + if (!block_range.GetBaseAddress().IsValid()) + { + result.AppendErrorWithFormat("Could not find the current block address."); + result.SetStatus(eReturnStatusFailed); + return false; + } + lldb::addr_t pc_offset_in_block = pc_address.GetFileAddress() - block_range.GetBaseAddress().GetFileAddress(); + lldb::addr_t range_length = block_range.GetByteSize() - pc_offset_in_block; + range = AddressRange(pc_address, range_length); + } + else + { + range = sc.line_entry.range; + } + new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, - frame->GetSymbolContext(eSymbolContextEverything).line_entry, - frame->GetSymbolContext(eSymbolContextEverything), - m_options.m_step_in_target.c_str(), - stop_other_threads, - m_options.m_step_in_avoid_no_debug, - m_options.m_step_out_avoid_no_debug); + range, + frame->GetSymbolContext(eSymbolContextEverything), + m_options.m_step_in_target.c_str(), + stop_other_threads, + m_options.m_step_in_avoid_no_debug, + m_options.m_step_out_avoid_no_debug); if (new_plan_sp && !m_options.m_avoid_regexp.empty()) { @@ -601,7 +652,6 @@ protected: } else new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads); - } else if (m_step_type == eStepTypeOver) { @@ -617,7 +667,6 @@ protected: new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads); - } else if (m_step_type == eStepTypeTrace) { @@ -629,14 +678,14 @@ protected: } else if (m_step_type == eStepTypeOut) { - new_plan_sp = thread->QueueThreadPlanForStepOut (abort_other_plans, - NULL, - false, - bool_stop_other_threads, - eVoteYes, - eVoteNoOpinion, - thread->GetSelectedFrameIndex(), - m_options.m_step_out_avoid_no_debug); + new_plan_sp = thread->QueueThreadPlanForStepOut(abort_other_plans, + nullptr, + false, + bool_stop_other_threads, + eVoteYes, + eVoteNoOpinion, + thread->GetSelectedFrameIndex(), + m_options.m_step_out_avoid_no_debug); } else if (m_step_type == eStepTypeScripted) { @@ -667,7 +716,6 @@ protected: } } - process->GetThreadList().SetSelectedThreadByID (thread->GetID()); const uint32_t iohandler_id = process->GetIOHandlerID(); @@ -719,7 +767,7 @@ g_tri_running_mode[] = { eOnlyThisThread, "this-thread", "Run only this thread"}, { eAllThreads, "all-threads", "Run all threads"}, { eOnlyDuringStepping, "while-stepping", "Run only this thread while stepping"}, -{ 0, NULL, NULL } +{ 0, nullptr, nullptr } }; static OptionEnumValueElement @@ -727,23 +775,25 @@ g_duo_running_mode[] = { { eOnlyThisThread, "this-thread", "Run only this thread"}, { eAllThreads, "all-threads", "Run all threads"}, -{ 0, NULL, NULL } +{ 0, nullptr, nullptr } }; OptionDefinition CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."}, -{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."}, -{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."}, -{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, NULL, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."}, -{ LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."}, -{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."}, -{ LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."}, -{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information."}, +{ LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information."}, +{ LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst."}, +{ LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over." + " You can also pass the string 'block' to step to the end of the current block." + " This is particularly useful in conjunction with --step-target to step through a complex calling sequence."}, +{ LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."}, +{ LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."}, +{ LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."}, +{ LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step."}, +{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } }; - //------------------------------------------------------------------------- // CommandObjectThreadContinue //------------------------------------------------------------------------- @@ -751,16 +801,12 @@ CommandObjectThreadStepWithTypeAndScope::CommandOptions::g_option_table[] = class CommandObjectThreadContinue : public CommandObjectParsed { public: - - CommandObjectThreadContinue (CommandInterpreter &interpreter) : - CommandObjectParsed (interpreter, - "thread continue", - "Continue execution of one or more threads in an active process.", - NULL, - eCommandRequiresThread | - eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused) + CommandObjectThreadContinue(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "thread continue", "Continue execution of the current target process. One " + "or more threads may be specified, by default all " + "threads continue.", + nullptr, eCommandRequiresThread | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) { CommandArgumentEntry arg; CommandArgumentData thread_idx_arg; @@ -776,17 +822,14 @@ public: m_arguments.push_back (arg); } - - ~CommandObjectThreadContinue () override - { - } + ~CommandObjectThreadContinue() override = default; bool DoExecute (Args& command, CommandReturnObject &result) override { bool synchronous_execution = m_interpreter.GetSynchronous (); - if (!m_interpreter.GetDebugger().GetSelectedTarget().get()) + if (!m_interpreter.GetDebugger().GetSelectedTarget()) { result.AppendError ("invalid target, create a debug target using the 'target create' command"); result.SetStatus (eReturnStatusFailed); @@ -794,7 +837,7 @@ public: } Process *process = m_exe_ctx.GetProcessPtr(); - if (process == NULL) + if (process == nullptr) { result.AppendError ("no process exists. Cannot continue"); result.SetStatus (eReturnStatusFailed); @@ -810,10 +853,10 @@ public: // These two lines appear at the beginning of both blocks in // this if..else, but that is because we need to release the // lock before calling process->Resume below. - Mutex::Locker locker (process->GetThreadList().GetMutex()); + std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex()); const uint32_t num_threads = process->GetThreadList().GetSize(); std::vector<Thread *> resume_threads; - for (uint32_t i=0; i<argc; ++i) + for (uint32_t i = 0; i < argc; ++i) { bool success; const int base = 0; @@ -854,7 +897,7 @@ public: else result.AppendMessageWithFormat ("Resuming threads: "); - for (uint32_t idx=0; idx<num_threads; ++idx) + for (uint32_t idx = 0; idx < num_threads; ++idx) { Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); std::vector<Thread *>::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread); @@ -862,7 +905,7 @@ public: if (this_thread_pos != resume_threads.end()) { resume_threads.erase(this_thread_pos); - if (resume_threads.size() > 0) + if (!resume_threads.empty()) result.AppendMessageWithFormat ("%u, ", thread->GetIndexID()); else result.AppendMessageWithFormat ("%u ", thread->GetIndexID()); @@ -883,17 +926,17 @@ public: // These two lines appear at the beginning of both blocks in // this if..else, but that is because we need to release the // lock before calling process->Resume below. - Mutex::Locker locker (process->GetThreadList().GetMutex()); + std::lock_guard<std::recursive_mutex> guard(process->GetThreadList().GetMutex()); const uint32_t num_threads = process->GetThreadList().GetSize(); - Thread *current_thread = process->GetThreadList().GetSelectedThread().get(); - if (current_thread == NULL) + Thread *current_thread = GetDefaultThread(); + if (current_thread == nullptr) { result.AppendError ("the process doesn't have a current thread"); result.SetStatus (eReturnStatusFailed); return false; } // Set the actions that the threads should each take when resuming - for (uint32_t idx=0; idx<num_threads; ++idx) + for (uint32_t idx = 0; idx < num_threads; ++idx) { Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get(); if (thread == current_thread) @@ -909,7 +952,6 @@ public: } } - StreamString stream; Error error; if (synchronous_execution) @@ -950,7 +992,6 @@ public: return result.Succeeded(); } - }; //------------------------------------------------------------------------- @@ -960,7 +1001,6 @@ public: class CommandObjectThreadUntil : public CommandObjectParsed { public: - class CommandOptions : public Options { public: @@ -976,9 +1016,7 @@ public: OptionParsingStarting (); } - ~CommandOptions () override - { - } + ~CommandOptions() override = default; Error SetOptionValue (uint32_t option_idx, const char *option_arg) override @@ -997,23 +1035,19 @@ public: } break; case 't': - { m_thread_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_INDEX32); if (m_thread_idx == LLDB_INVALID_INDEX32) { error.SetErrorStringWithFormat ("invalid thread index '%s'", option_arg); } - } - break; + break; case 'f': - { m_frame_idx = StringConvert::ToUInt32 (option_arg, LLDB_INVALID_FRAME_ID); if (m_frame_idx == LLDB_INVALID_FRAME_ID) { error.SetErrorStringWithFormat ("invalid frame index '%s'", option_arg); } - } - break; + break; case 'm': { OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; @@ -1031,7 +1065,6 @@ public: default: error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); break; - } return error; } @@ -1062,16 +1095,13 @@ public: // Instance variables to hold the values for command options. }; - CommandObjectThreadUntil (CommandInterpreter &interpreter) : - CommandObjectParsed (interpreter, - "thread until", - "Run the current or specified thread until it reaches a given line number or address or leaves the current function.", - NULL, - eCommandRequiresThread | - eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused ), - m_options (interpreter) + CommandObjectThreadUntil(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "thread until", "Continue until a line number or address is reached by the " + "current or specified thread. Stops when returning from " + "the current function as a safety measure.", + nullptr, eCommandRequiresThread | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), + m_options(interpreter) { CommandArgumentEntry arg; CommandArgumentData line_num_arg; @@ -1087,10 +1117,7 @@ public: m_arguments.push_back (arg); } - - ~CommandObjectThreadUntil () override - { - } + ~CommandObjectThreadUntil() override = default; Options * GetOptions () override @@ -1105,7 +1132,7 @@ protected: bool synchronous_execution = m_interpreter.GetSynchronous (); Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); - if (target == NULL) + if (target == nullptr) { result.AppendError ("invalid target, create a debug target using the 'target create' command"); result.SetStatus (eReturnStatusFailed); @@ -1113,15 +1140,14 @@ protected: } Process *process = m_exe_ctx.GetProcessPtr(); - if (process == NULL) + if (process == nullptr) { result.AppendError ("need a valid process to step"); result.SetStatus (eReturnStatusFailed); - } else { - Thread *thread = NULL; + Thread *thread = nullptr; std::vector<uint32_t> line_numbers; if (command.GetArgumentCount() >= 1) @@ -1148,17 +1174,16 @@ protected: return false; } - if (m_options.m_thread_idx == LLDB_INVALID_THREAD_ID) { - thread = process->GetThreadList().GetSelectedThread().get(); + thread = GetDefaultThread(); } else { thread = process->GetThreadList().FindThreadByIndexID(m_options.m_thread_idx).get(); } - if (thread == NULL) + if (thread == nullptr) { const uint32_t num_threads = process->GetThreadList().GetSize(); result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n", @@ -1171,9 +1196,8 @@ protected: const bool abort_other_plans = false; StackFrame *frame = thread->GetStackFrameAtIndex(m_options.m_frame_idx).get(); - if (frame == NULL) + if (frame == nullptr) { - result.AppendErrorWithFormat ("Frame index %u is out of range for thread %u.\n", m_options.m_frame_idx, m_options.m_thread_idx); @@ -1187,11 +1211,11 @@ protected: { // Finally we got here... Translate the given line number to a bunch of addresses: SymbolContext sc(frame->GetSymbolContext (eSymbolContextCompUnit)); - LineTable *line_table = NULL; + LineTable *line_table = nullptr; if (sc.comp_unit) line_table = sc.comp_unit->GetLineTable(); - if (line_table == NULL) + if (line_table == nullptr) { result.AppendErrorWithFormat ("Failed to resolve the line table for frame %u of thread index %u.\n", m_options.m_frame_idx, m_options.m_thread_idx); @@ -1246,7 +1270,7 @@ protected: all_in_function = false; } - if (address_list.size() == 0) + if (address_list.empty()) { if (all_in_function) result.AppendErrorWithFormat ("No line entries matching until target.\n"); @@ -1275,11 +1299,8 @@ protected: m_options.m_thread_idx); result.SetStatus (eReturnStatusFailed); return false; - } - - process->GetThreadList().SetSelectedThreadByID (m_options.m_thread_idx); StreamString stream; @@ -1317,20 +1338,18 @@ protected: } CommandOptions m_options; - }; OptionDefinition 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, "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 } +{ LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0"}, +{ LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation"}, +{ LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, nullptr, 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, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times."}, +{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } }; - //------------------------------------------------------------------------- // CommandObjectThreadSelect //------------------------------------------------------------------------- @@ -1338,16 +1357,10 @@ CommandObjectThreadUntil::CommandOptions::g_option_table[] = class CommandObjectThreadSelect : public CommandObjectParsed { public: - - CommandObjectThreadSelect (CommandInterpreter &interpreter) : - CommandObjectParsed (interpreter, - "thread select", - "Select a thread as the currently active thread.", - NULL, - eCommandRequiresProcess | - eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused ) + CommandObjectThreadSelect(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "thread select", "Change the currently selected thread.", nullptr, + eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused) { CommandArgumentEntry arg; CommandArgumentData thread_idx_arg; @@ -1363,17 +1376,14 @@ public: m_arguments.push_back (arg); } - - ~CommandObjectThreadSelect () override - { - } + ~CommandObjectThreadSelect() override = default; protected: bool DoExecute (Args& command, CommandReturnObject &result) override { Process *process = m_exe_ctx.GetProcessPtr(); - if (process == NULL) + if (process == nullptr) { result.AppendError ("no process"); result.SetStatus (eReturnStatusFailed); @@ -1389,7 +1399,7 @@ protected: uint32_t index_id = StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); Thread *new_thread = process->GetThreadList().FindThreadByIndexID(index_id).get(); - if (new_thread == NULL) + if (new_thread == nullptr) { result.AppendErrorWithFormat ("invalid thread #%s.\n", command.GetArgumentAtIndex(0)); result.SetStatus (eReturnStatusFailed); @@ -1401,10 +1411,8 @@ protected: return result.Succeeded(); } - }; - //------------------------------------------------------------------------- // CommandObjectThreadList //------------------------------------------------------------------------- @@ -1412,23 +1420,15 @@ protected: class CommandObjectThreadList : public CommandObjectParsed { public: - - - CommandObjectThreadList (CommandInterpreter &interpreter): - CommandObjectParsed (interpreter, - "thread list", - "Show a summary of all current threads in a process.", - "thread list", - eCommandRequiresProcess | - eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused ) + CommandObjectThreadList(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "thread list", + "Show a summary of each thread in the current target process.", "thread list", + eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused) { } - ~CommandObjectThreadList() override - { - } + ~CommandObjectThreadList() override = default; protected: bool @@ -1458,31 +1458,17 @@ protected: class CommandObjectThreadInfo : public CommandObjectIterateOverThreads { public: - - CommandObjectThreadInfo (CommandInterpreter &interpreter) : - CommandObjectIterateOverThreads (interpreter, - "thread info", - "Show an extended summary of information about thread(s) in a process.", - "thread info", - eCommandRequiresProcess | - eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused), - m_options (interpreter) - { - m_add_return = false; - } - class CommandOptions : public Options { public: - CommandOptions (CommandInterpreter &interpreter) : Options (interpreter) { OptionParsingStarting (); } + ~CommandOptions() override = default; + void OptionParsingStarting () override { @@ -1490,10 +1476,6 @@ public: m_json_stopinfo = false; } - ~CommandOptions () override - { - } - Error SetOptionValue (uint32_t option_idx, const char *option_arg) override { @@ -1512,7 +1494,6 @@ public: default: return Error("invalid short option character '%c'", short_option); - } return error; } @@ -1529,23 +1510,42 @@ public: static OptionDefinition g_option_table[]; }; - Options * - GetOptions () override + CommandObjectThreadInfo(CommandInterpreter &interpreter) + : CommandObjectIterateOverThreads( + interpreter, "thread info", + "Show an extended summary of one or more threads. Defaults to the current thread.", "thread info", + eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched | + eCommandProcessMustBePaused), + m_options(interpreter) { - return &m_options; + m_add_return = false; } - ~CommandObjectThreadInfo () override + ~CommandObjectThreadInfo() override = default; + + Options * + GetOptions () override { + return &m_options; } bool - HandleOneThread (Thread &thread, CommandReturnObject &result) override + HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override { + ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); + if (!thread_sp) + { + result.AppendErrorWithFormat ("thread no longer exists: 0x%" PRIx64 "\n", tid); + result.SetStatus (eReturnStatusFailed); + return false; + } + + Thread *thread = thread_sp.get(); + Stream &strm = result.GetOutputStream(); - if (!thread.GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo)) + if (!thread->GetDescription (strm, eDescriptionLevelFull, m_options.m_json_thread, m_options.m_json_stopinfo)) { - result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread.GetIndexID()); + result.AppendErrorWithFormat ("error displaying info for thread: \"%d\"\n", thread->GetIndexID()); result.SetStatus (eReturnStatusFailed); return false; } @@ -1553,19 +1553,17 @@ public: } CommandOptions m_options; - }; OptionDefinition CommandObjectThreadInfo::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the thread info in JSON format."}, - { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the extended stop info in JSON format."}, + { LLDB_OPT_SET_ALL, false, "json",'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format."}, + { LLDB_OPT_SET_ALL, false, "stop-info",'s', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the extended stop info in JSON format."}, - { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } + { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } }; - //------------------------------------------------------------------------- // CommandObjectThreadReturn //------------------------------------------------------------------------- @@ -1576,7 +1574,6 @@ public: class CommandOptions : public Options { public: - CommandOptions (CommandInterpreter &interpreter) : Options (interpreter), m_from_expression (false) @@ -1585,9 +1582,7 @@ public: OptionParsingStarting (); } - ~CommandOptions () override - { - } + ~CommandOptions() override = default; Error SetOptionValue (uint32_t option_idx, const char *option_arg) override @@ -1612,7 +1607,6 @@ public: default: error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); break; - } return error; } @@ -1638,23 +1632,14 @@ public: // Instance variables to hold the values for command options. }; - Options * - GetOptions () override - { - return &m_options; - } - - CommandObjectThreadReturn (CommandInterpreter &interpreter) : - CommandObjectRaw (interpreter, - "thread return", - "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value," - " or with the -x option from the innermost function evaluation.", - "thread return", - eCommandRequiresFrame | - eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused ), - m_options (interpreter) + CommandObjectThreadReturn(CommandInterpreter &interpreter) + : CommandObjectRaw(interpreter, "thread return", + "Prematurely return from a stack frame, short-circuiting execution of newer frames " + "and optionally yielding a specified value. Defaults to the exiting the current stack " + "frame.", + "thread return", eCommandRequiresFrame | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), + m_options(interpreter) { CommandArgumentEntry arg; CommandArgumentData expression_arg; @@ -1668,16 +1653,17 @@ public: // Push the data for the first argument into the m_arguments vector. m_arguments.push_back (arg); - - } - - ~CommandObjectThreadReturn() override + + ~CommandObjectThreadReturn() override = default; + + Options * + GetOptions() override { + return &m_options; } - -protected: +protected: bool DoExecute (const char *command, CommandReturnObject &result) override { @@ -1746,7 +1732,6 @@ protected: result.AppendErrorWithFormat("Unknown error evaluating result expression."); result.SetStatus (eReturnStatusFailed); return false; - } } @@ -1766,13 +1751,13 @@ protected: } CommandOptions m_options; - }; + OptionDefinition CommandObjectThreadReturn::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."}, -{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation."}, +{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } }; //------------------------------------------------------------------------- @@ -1785,13 +1770,14 @@ public: class CommandOptions : public Options { public: - CommandOptions (CommandInterpreter &interpreter) : Options (interpreter) { OptionParsingStarting (); } + ~CommandOptions() override = default; + void OptionParsingStarting () override { @@ -1802,10 +1788,6 @@ public: m_force = false; } - ~CommandOptions () override - { - } - Error SetOptionValue (uint32_t option_idx, const char *option_arg) override { @@ -1839,10 +1821,8 @@ public: case 'r': m_force = true; break; - default: return Error("invalid short option character '%c'", short_option); - } return error; } @@ -1862,12 +1842,6 @@ public: static OptionDefinition g_option_table[]; }; - Options * - GetOptions () override - { - return &m_options; - } - CommandObjectThreadJump (CommandInterpreter &interpreter) : CommandObjectParsed (interpreter, "thread jump", @@ -1881,12 +1855,15 @@ public: { } - ~CommandObjectThreadJump() override + ~CommandObjectThreadJump() override = default; + + Options * + GetOptions() override { + return &m_options; } protected: - bool DoExecute (Args& args, CommandReturnObject &result) override { RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext(); @@ -1953,44 +1930,43 @@ protected: CommandOptions m_options; }; + OptionDefinition CommandObjectThreadJump::CommandOptions::g_option_table[] = { - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, + { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file to jump to."}, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, + { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number to jump to."}, - { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, + { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "Jumps by a relative line offset from the current line."}, - { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, + { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Jumps to a specific address."}, { LLDB_OPT_SET_1| LLDB_OPT_SET_2| - LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,"Allows the PC to leave the current function."}, + LLDB_OPT_SET_3, false, "force",'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone,"Allows the PC to leave the current function."}, - { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } + { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } }; //------------------------------------------------------------------------- // Next are the subcommands of CommandObjectMultiwordThreadPlan //------------------------------------------------------------------------- - //------------------------------------------------------------------------- // CommandObjectThreadPlanList //------------------------------------------------------------------------- + class CommandObjectThreadPlanList : public CommandObjectIterateOverThreads { public: - class CommandOptions : public Options { public: - CommandOptions (CommandInterpreter &interpreter) : Options(interpreter) { @@ -1998,9 +1974,7 @@ public: OptionParsingStarting (); } - ~CommandOptions () override - { - } + ~CommandOptions() override = default; Error SetOptionValue (uint32_t option_idx, const char *option_arg) override @@ -2011,19 +1985,14 @@ public: switch (short_option) { case 'i': - { m_internal = true; - } - break; + break; case 'v': - { m_verbose = true; - } - break; + break; default: error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); break; - } return error; } @@ -2050,24 +2019,18 @@ public: bool m_internal; }; - CommandObjectThreadPlanList (CommandInterpreter &interpreter) : - CommandObjectIterateOverThreads (interpreter, - "thread plan list", - "Show thread plans for one or more threads. If no threads are specified, show the " - "currently selected thread. Use the thread-index \"all\" to see all threads.", - NULL, - eCommandRequiresProcess | - eCommandRequiresThread | - eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused ), - m_options(interpreter) + CommandObjectThreadPlanList(CommandInterpreter &interpreter) + : CommandObjectIterateOverThreads( + interpreter, "thread plan list", + "Show thread plans for one or more threads. If no threads are specified, show the " + "current thread. Use the thread-index \"all\" to see all threads.", + nullptr, eCommandRequiresProcess | eCommandRequiresThread | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), + m_options(interpreter) { } - ~CommandObjectThreadPlanList () override - { - } + ~CommandObjectThreadPlanList() override = default; Options * GetOptions () override @@ -2077,42 +2040,48 @@ public: protected: bool - HandleOneThread (Thread &thread, CommandReturnObject &result) override + HandleOneThread (lldb::tid_t tid, CommandReturnObject &result) override { + ThreadSP thread_sp = m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); + if (!thread_sp) + { + result.AppendErrorWithFormat ("thread no longer exists: 0x%" PRIx64 "\n", tid); + result.SetStatus (eReturnStatusFailed); + return false; + } + + Thread *thread = thread_sp.get(); + Stream &strm = result.GetOutputStream(); DescriptionLevel desc_level = eDescriptionLevelFull; if (m_options.m_verbose) desc_level = eDescriptionLevelVerbose; - thread.DumpThreadPlans (&strm, desc_level, m_options.m_internal, true); + thread->DumpThreadPlans (&strm, desc_level, m_options.m_internal, true); return true; } + CommandOptions m_options; }; OptionDefinition CommandObjectThreadPlanList::CommandOptions::g_option_table[] = { -{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display more information about the thread plans"}, -{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display internal as well as user thread plans"}, -{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } +{ LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans"}, +{ LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans"}, +{ 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr } }; class CommandObjectThreadPlanDiscard : public CommandObjectParsed { public: - CommandObjectThreadPlanDiscard (CommandInterpreter &interpreter) : - CommandObjectParsed (interpreter, - "thread plan discard", - "Discards thread plans up to and including the plan passed as the command argument." - "Only user visible plans can be discarded, use the index from \"thread plan list\"" - " without the \"-i\" argument.", - NULL, - eCommandRequiresProcess | - eCommandRequiresThread | - eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused ) + CommandObjectThreadPlanDiscard(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "thread plan discard", + "Discards thread plans up to and including the specified index (see 'thread plan list'.) " + "Only user visible plans can be discarded.", + nullptr, eCommandRequiresProcess | eCommandRequiresThread | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) { CommandArgumentEntry arg; CommandArgumentData plan_index_arg; @@ -2128,7 +2097,7 @@ public: m_arguments.push_back (arg); } - ~CommandObjectThreadPlanDiscard () override {} + ~CommandObjectThreadPlanDiscard() override = default; bool DoExecute (Args& args, CommandReturnObject &result) override @@ -2181,30 +2150,25 @@ public: class CommandObjectMultiwordThreadPlan : public CommandObjectMultiword { public: - CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) : - CommandObjectMultiword (interpreter, - "plan", - "A set of subcommands for accessing the thread plans controlling execution control on one or more threads.", - "thread plan <subcommand> [<subcommand objects]") + CommandObjectMultiwordThreadPlan(CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "plan", "Commands for managing thread plans that control execution.", + "thread plan <subcommand> [<subcommand objects]") { LoadSubCommand ("list", CommandObjectSP (new CommandObjectThreadPlanList (interpreter))); LoadSubCommand ("discard", CommandObjectSP (new CommandObjectThreadPlanDiscard (interpreter))); } - ~CommandObjectMultiwordThreadPlan () override {} - - + ~CommandObjectMultiwordThreadPlan() override = default; }; //------------------------------------------------------------------------- // CommandObjectMultiwordThread //------------------------------------------------------------------------- -CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter &interpreter) : - CommandObjectMultiword (interpreter, - "thread", - "A set of commands for operating on one or more threads within a running process.", - "thread <subcommand> [<subcommand-options>]") +CommandObjectMultiwordThread::CommandObjectMultiwordThread(CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "thread", + "Commands for operating on one or more threads in the current process.", + "thread <subcommand> [<subcommand-options>]") { LoadSubCommand ("backtrace", CommandObjectSP (new CommandObjectThreadBacktrace (interpreter))); LoadSubCommand ("continue", CommandObjectSP (new CommandObjectThreadContinue (interpreter))); @@ -2214,59 +2178,47 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread (CommandInterpreter & LoadSubCommand ("select", CommandObjectSP (new CommandObjectThreadSelect (interpreter))); LoadSubCommand ("until", CommandObjectSP (new CommandObjectThreadUntil (interpreter))); LoadSubCommand ("info", CommandObjectSP (new CommandObjectThreadInfo (interpreter))); - LoadSubCommand ("step-in", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( - interpreter, - "thread step-in", - "Source level single step in specified thread (current thread, if none specified).", - NULL, - eStepTypeInto, - eStepScopeSource))); - - LoadSubCommand ("step-out", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( - interpreter, - "thread step-out", - "Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).", - NULL, - eStepTypeOut, - eStepScopeSource))); - - LoadSubCommand ("step-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( - interpreter, - "thread step-over", - "Source level single step in specified thread (current thread, if none specified), stepping over calls.", - NULL, - eStepTypeOver, - eStepScopeSource))); - - LoadSubCommand ("step-inst", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( - interpreter, - "thread step-inst", - "Single step one instruction in specified thread (current thread, if none specified).", - NULL, - eStepTypeTrace, - eStepScopeInstruction))); - - LoadSubCommand ("step-inst-over", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( - interpreter, - "thread step-inst-over", - "Single step one instruction in specified thread (current thread, if none specified), stepping over calls.", - NULL, - eStepTypeTraceOver, - eStepScopeInstruction))); + LoadSubCommand("step-in", + CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( + interpreter, "thread step-in", + "Source level single step, stepping into calls. Defaults to current thread unless specified.", + nullptr, eStepTypeInto, eStepScopeSource))); + + LoadSubCommand("step-out", + CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( + interpreter, "thread step-out", "Finish executing the current stack frame and stop after " + "returning. Defaults to current thread unless specified.", + nullptr, eStepTypeOut, eStepScopeSource))); + + LoadSubCommand("step-over", + CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( + interpreter, "thread step-over", + "Source level single step, stepping over calls. Defaults to current thread unless specified.", + nullptr, eStepTypeOver, eStepScopeSource))); + + LoadSubCommand( + "step-inst", + CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( + interpreter, "thread step-inst", + "Instruction level single step, stepping into calls. Defaults to current thread unless specified.", + nullptr, eStepTypeTrace, eStepScopeInstruction))); + + LoadSubCommand( + "step-inst-over", + CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( + interpreter, "thread step-inst-over", + "Instruction level single step, stepping over calls. Defaults to current thread unless specified.", + nullptr, eStepTypeTraceOver, eStepScopeInstruction))); LoadSubCommand ("step-scripted", CommandObjectSP (new CommandObjectThreadStepWithTypeAndScope ( interpreter, "thread step-scripted", "Step as instructed by the script class passed in the -C option.", - NULL, + nullptr, eStepTypeScripted, eStepScopeSource))); LoadSubCommand ("plan", CommandObjectSP (new CommandObjectMultiwordThreadPlan(interpreter))); } -CommandObjectMultiwordThread::~CommandObjectMultiwordThread () -{ -} - - +CommandObjectMultiwordThread::~CommandObjectMultiwordThread() = default; |