This works for Python commands defined via a class (implement get_flags on your class) and C++ plugin commands (which can call SBCommand::GetFlags()/SetFlags())
Flags allow features such as not letting the command run if there's no target, or if the process is not stopped, ...
Commands could always check for these things themselves, but having these accessible via flags makes custom commands more consistent with built-in ones
llvm-svn: 238286
void
SetHelpLong (const char*);
+ uint32_t
+ GetFlags ();
+
+ void
+ SetFlags (uint32_t flags);
+
lldb::SBCommand
AddMultiwordCommand (const char* name, const char* help = NULL);
bool
IsPairType (ArgumentRepetitionType arg_repeat_type);
-
- enum
- {
- //----------------------------------------------------------------------
- // eFlagRequiresTarget
- //
- // Ensures a valid target is contained in m_exe_ctx prior to executing
- // the command. If a target doesn't exist or is invalid, the command
- // will fail and CommandObject::GetInvalidTargetDescription() will be
- // returned as the error. CommandObject subclasses can override the
- // virtual function for GetInvalidTargetDescription() to provide custom
- // strings when needed.
- //----------------------------------------------------------------------
- eFlagRequiresTarget = (1u << 0),
- //----------------------------------------------------------------------
- // eFlagRequiresProcess
- //
- // Ensures a valid process is contained in m_exe_ctx prior to executing
- // the command. If a process doesn't exist or is invalid, the command
- // will fail and CommandObject::GetInvalidProcessDescription() will be
- // returned as the error. CommandObject subclasses can override the
- // virtual function for GetInvalidProcessDescription() to provide custom
- // strings when needed.
- //----------------------------------------------------------------------
- eFlagRequiresProcess = (1u << 1),
- //----------------------------------------------------------------------
- // eFlagRequiresThread
- //
- // Ensures a valid thread is contained in m_exe_ctx prior to executing
- // the command. If a thread doesn't exist or is invalid, the command
- // will fail and CommandObject::GetInvalidThreadDescription() will be
- // returned as the error. CommandObject subclasses can override the
- // virtual function for GetInvalidThreadDescription() to provide custom
- // strings when needed.
- //----------------------------------------------------------------------
- eFlagRequiresThread = (1u << 2),
- //----------------------------------------------------------------------
- // eFlagRequiresFrame
- //
- // Ensures a valid frame is contained in m_exe_ctx prior to executing
- // the command. If a frame doesn't exist or is invalid, the command
- // will fail and CommandObject::GetInvalidFrameDescription() will be
- // returned as the error. CommandObject subclasses can override the
- // virtual function for GetInvalidFrameDescription() to provide custom
- // strings when needed.
- //----------------------------------------------------------------------
- eFlagRequiresFrame = (1u << 3),
- //----------------------------------------------------------------------
- // eFlagRequiresRegContext
- //
- // Ensures a valid register context (from the selected frame if there
- // is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
- // is available from m_exe_ctx prior to executing the command. If a
- // target doesn't exist or is invalid, the command will fail and
- // CommandObject::GetInvalidRegContextDescription() will be returned as
- // the error. CommandObject subclasses can override the virtual function
- // for GetInvalidRegContextDescription() to provide custom strings when
- // needed.
- //----------------------------------------------------------------------
- eFlagRequiresRegContext = (1u << 4),
- //----------------------------------------------------------------------
- // eFlagTryTargetAPILock
- //
- // Attempts to acquire the target lock if a target is selected in the
- // command interpreter. If the command object fails to acquire the API
- // lock, the command will fail with an appropriate error message.
- //----------------------------------------------------------------------
- eFlagTryTargetAPILock = (1u << 5),
- //----------------------------------------------------------------------
- // eFlagProcessMustBeLaunched
- //
- // Verifies that there is a launched process in m_exe_ctx, if there
- // isn't, the command will fail with an appropriate error message.
- //----------------------------------------------------------------------
- eFlagProcessMustBeLaunched = (1u << 6),
- //----------------------------------------------------------------------
- // eFlagProcessMustBePaused
- //
- // Verifies that there is a paused process in m_exe_ctx, if there
- // isn't, the command will fail with an appropriate error message.
- //----------------------------------------------------------------------
- eFlagProcessMustBePaused = (1u << 7)
- };
bool
ParseOptions (Args& args, CommandReturnObject &result);
dest.clear();
return false;
}
+
+ virtual uint32_t
+ GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp)
+ {
+ return 0;
+ }
virtual bool
GetLongHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
bool
GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string& dest) override;
+ uint32_t
+ GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp) override;
+
bool
GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string& dest) override;
eTypeIsSigned = (1u << 21)
};
+ FLAGS_ENUM(CommandFlags)
+ {
+ //----------------------------------------------------------------------
+ // eCommandRequiresTarget
+ //
+ // Ensures a valid target is contained in m_exe_ctx prior to executing
+ // the command. If a target doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidTargetDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidTargetDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eCommandRequiresTarget = (1u << 0),
+ //----------------------------------------------------------------------
+ // eCommandRequiresProcess
+ //
+ // Ensures a valid process is contained in m_exe_ctx prior to executing
+ // the command. If a process doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidProcessDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidProcessDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eCommandRequiresProcess = (1u << 1),
+ //----------------------------------------------------------------------
+ // eCommandRequiresThread
+ //
+ // Ensures a valid thread is contained in m_exe_ctx prior to executing
+ // the command. If a thread doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidThreadDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidThreadDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eCommandRequiresThread = (1u << 2),
+ //----------------------------------------------------------------------
+ // eCommandRequiresFrame
+ //
+ // Ensures a valid frame is contained in m_exe_ctx prior to executing
+ // the command. If a frame doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidFrameDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidFrameDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eCommandRequiresFrame = (1u << 3),
+ //----------------------------------------------------------------------
+ // eCommandRequiresRegContext
+ //
+ // Ensures a valid register context (from the selected frame if there
+ // is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
+ // is available from m_exe_ctx prior to executing the command. If a
+ // target doesn't exist or is invalid, the command will fail and
+ // CommandObject::GetInvalidRegContextDescription() will be returned as
+ // the error. CommandObject subclasses can override the virtual function
+ // for GetInvalidRegContextDescription() to provide custom strings when
+ // needed.
+ //----------------------------------------------------------------------
+ eCommandRequiresRegContext = (1u << 4),
+ //----------------------------------------------------------------------
+ // eCommandTryTargetAPILock
+ //
+ // Attempts to acquire the target lock if a target is selected in the
+ // command interpreter. If the command object fails to acquire the API
+ // lock, the command will fail with an appropriate error message.
+ //----------------------------------------------------------------------
+ eCommandTryTargetAPILock = (1u << 5),
+ //----------------------------------------------------------------------
+ // eCommandProcessMustBeLaunched
+ //
+ // Verifies that there is a launched process in m_exe_ctx, if there
+ // isn't, the command will fail with an appropriate error message.
+ //----------------------------------------------------------------------
+ eCommandProcessMustBeLaunched = (1u << 6),
+ //----------------------------------------------------------------------
+ // eCommandProcessMustBePaused
+ //
+ // Verifies that there is a paused process in m_exe_ctx, if there
+ // isn't, the command will fail with an appropriate error message.
+ //----------------------------------------------------------------------
+ eCommandProcessMustBePaused = (1u << 7)
+ };
+
//----------------------------------------------------------------------
// Whether a summary should cap how much data it returns to users or not
//----------------------------------------------------------------------
launchStyle = "0"
useCustomWorkingDirectory = "NO"
customWorkingDirectory = "/Volumes/work/gclayton/Documents/devb/attach"
- buildConfiguration = "Debug"
+ buildConfiguration = "DebugClang"
ignoresPersistentStateOnLaunch = "YES"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
return lldb::SBCommand(new_command_sp);
return lldb::SBCommand();
}
+
+uint32_t
+SBCommand::GetFlags ()
+{
+ if (!IsValid())
+ return 0;
+ return m_opaque_sp->GetFlags().Get();
+}
+
+void
+SBCommand::SetFlags (uint32_t flags)
+{
+ if (IsValid())
+ m_opaque_sp->GetFlags().Set(flags);
+}
StreamString stream;
stream.Printf("For more information run 'help %s'",name.c_str());
SetHelp(stream.GetData());
+ if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
+ GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
}
virtual
"expression",
"Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
NULL,
- eFlagProcessMustBePaused | eFlagTryTargetAPILock),
+ eCommandProcessMustBePaused | eCommandTryTargetAPILock),
IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
m_option_group (interpreter),
m_format_options (eFormatDefault),
"frame info",
"List information about the currently selected frame in the current thread.",
"frame info",
- eFlagRequiresFrame |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused )
+ eCommandRequiresFrame |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused )
{
}
"frame select",
"Select a frame by index from within the current thread and make it the current frame.",
NULL,
- eFlagRequiresThread |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresThread |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_options (interpreter)
{
CommandArgumentEntry arg;
bool
DoExecute (Args& command, CommandReturnObject &result)
{
- // No need to check "thread" for validity as eFlagRequiresThread ensures it is valid
+ // No need to check "thread" for validity as eCommandRequiresThread ensures it is valid
Thread *thread = m_exe_ctx.GetThreadPtr();
uint32_t frame_idx = UINT32_MAX;
"Children of aggregate variables can be specified such as "
"'var->child.x'.",
NULL,
- eFlagRequiresFrame |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused |
- eFlagRequiresProcess),
+ eCommandRequiresFrame |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused |
+ eCommandRequiresProcess),
m_option_group (interpreter),
m_option_variable(true), // Include the frame specific options by passing "true"
m_option_format (eFormatDefault),
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- // No need to check "frame" for validity as eFlagRequiresFrame ensures it is valid
+ // No need to check "frame" for validity as eCommandRequiresFrame ensures it is valid
StackFrame *frame = m_exe_ctx.GetFramePtr();
Stream &s = result.GetOutputStream();
"memory read",
"Read from the memory of the process being debugged.",
NULL,
- eFlagRequiresTarget | eFlagProcessMustBePaused),
+ eCommandRequiresTarget | eCommandProcessMustBePaused),
m_option_group (interpreter),
m_format_options (eFormatBytesWithASCII, 1, 8),
m_memory_options (),
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- // No need to check "target" for validity as eFlagRequiresTarget ensures it is valid
+ // No need to check "target" for validity as eCommandRequiresTarget ensures it is valid
Target *target = m_exe_ctx.GetTargetPtr();
const size_t argc = command.GetArgumentCount();
"memory find",
"Find a value in the memory of the process being debugged.",
NULL,
- eFlagRequiresProcess | eFlagProcessMustBeLaunched),
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched),
m_option_group (interpreter),
m_memory_options ()
{
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
+ // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
Process *process = m_exe_ctx.GetProcessPtr();
const size_t argc = command.GetArgumentCount();
"memory write",
"Write to the memory of the process being debugged.",
NULL,
- eFlagRequiresProcess | eFlagProcessMustBeLaunched),
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched),
m_option_group (interpreter),
m_format_options (eFormatBytes, 1, UINT64_MAX),
m_memory_options ()
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
+ // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
Process *process = m_exe_ctx.GetProcessPtr();
const size_t argc = command.GetArgumentCount();
"memory history",
"Prints out the recorded stack traces for allocation/deallocation of a memory address.",
NULL,
- eFlagRequiresTarget | eFlagRequiresProcess | eFlagProcessMustBePaused | eFlagProcessMustBeLaunched)
+ eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBePaused | eCommandProcessMustBeLaunched)
{
CommandArgumentEntry arg1;
CommandArgumentData addr_arg;
"platform process launch",
"Launch a new process on a remote platform.",
"platform process launch program",
- eFlagRequiresTarget | eFlagTryTargetAPILock),
+ eCommandRequiresTarget | eCommandTryTargetAPILock),
m_options (interpreter)
{
}
"process launch",
"Launch the executable in the debugger.",
NULL,
- eFlagRequiresTarget,
+ eCommandRequiresTarget,
"restart"),
m_options (interpreter)
{
"process continue",
"Continue execution of all threads in the current process.",
"process continue",
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresProcess |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_options(interpreter)
{
}
"process detach",
"Detach from the current process being debugged.",
"process detach",
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched),
+ eCommandRequiresProcess |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched),
m_options(interpreter)
{
}
"process load",
"Load a shared library into the current process.",
"process load <filename> [<filename> ...]",
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused )
+ eCommandRequiresProcess |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused )
{
}
"process unload",
"Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
"process unload <index>",
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused )
+ eCommandRequiresProcess |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused )
{
}
"process signal",
"Send a UNIX signal to the current process being debugged.",
NULL,
- eFlagRequiresProcess | eFlagTryTargetAPILock)
+ eCommandRequiresProcess | eCommandTryTargetAPILock)
{
CommandArgumentEntry arg;
CommandArgumentData signal_arg;
"process interrupt",
"Interrupt the current process being debugged.",
"process interrupt",
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched)
+ eCommandRequiresProcess |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched)
{
}
"process kill",
"Terminate the current process being debugged.",
"process kill",
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched)
+ eCommandRequiresProcess |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched)
{
}
"process save-core",
"Save the current process as a core file using an appropriate file type.",
"process save-core FILE",
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched)
+ eCommandRequiresProcess |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched)
{
}
"process status",
"Show the current status and location of executing process.",
"process status",
- eFlagRequiresProcess | eFlagTryTargetAPILock)
+ eCommandRequiresProcess | eCommandTryTargetAPILock)
{
}
{
Stream &strm = result.GetOutputStream();
result.SetStatus (eReturnStatusSuccessFinishNoResult);
- // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
+ // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
Process *process = m_exe_ctx.GetProcessPtr();
const bool only_threads_with_stop_reason = true;
const uint32_t start_frame = 0;
"register read",
"Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.",
NULL,
- eFlagRequiresFrame |
- eFlagRequiresRegContext |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresFrame |
+ eCommandRequiresRegContext |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_option_group (interpreter),
m_format_options (eFormatDefault),
m_command_options ()
"register write",
"Modify a single register value.",
NULL,
- eFlagRequiresFrame |
- eFlagRequiresRegContext |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused)
+ eCommandRequiresFrame |
+ eCommandRequiresRegContext |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
"source list",
"Display source code (as specified) based on the current executable's debug info.",
NULL,
- eFlagRequiresTarget),
+ eCommandRequiresTarget),
m_options (interpreter)
{
}
"target variable",
"Read global variable(s) prior to, or while running your binary.",
NULL,
- eFlagRequiresTarget),
+ eCommandRequiresTarget),
m_option_group (interpreter),
m_option_variable (false), // Don't include frame options
m_option_format (eFormatDefault),
"target modules dump line-table",
"Dump the line table for one or more compilation units.",
NULL,
- eFlagRequiresTarget)
+ eCommandRequiresTarget)
{
}
"target modules show-unwind",
"Show synthesized unwind instructions for a function.",
NULL,
- eFlagRequiresTarget |
- eFlagRequiresProcess |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresTarget |
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_options (interpreter)
{
}
"target modules lookup",
"Look up information within executable and dependent shared library images.",
NULL,
- eFlagRequiresTarget),
+ eCommandRequiresTarget),
m_options (interpreter)
{
CommandArgumentEntry arg;
CommandObjectParsed (interpreter,
"target symbols add",
"Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.",
- "target symbols add [<symfile>]", eFlagRequiresTarget),
+ "target symbols add [<symfile>]", eCommandRequiresTarget),
m_option_group (interpreter),
m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
"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,
- eFlagRequiresProcess |
- eFlagRequiresThread |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresProcess |
+ eCommandRequiresThread |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_options(interpreter)
{
}
StepType step_type,
StepScope step_scope) :
CommandObjectParsed (interpreter, name, help, syntax,
- eFlagRequiresProcess |
- eFlagRequiresThread |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresProcess |
+ eCommandRequiresThread |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_step_type (step_type),
m_step_scope (step_scope),
m_options (interpreter)
"thread continue",
"Continue execution of one or more threads in an active process.",
NULL,
- eFlagRequiresThread |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused)
+ eCommandRequiresThread |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused)
{
CommandArgumentEntry arg;
CommandArgumentData thread_idx_arg;
"thread until",
"Run the current or specified thread until it reaches a given line number or address or leaves the current function.",
NULL,
- eFlagRequiresThread |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresThread |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_options (interpreter)
{
CommandArgumentEntry arg;
"thread select",
"Select a thread as the currently active thread.",
NULL,
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused )
+ eCommandRequiresProcess |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused )
{
CommandArgumentEntry arg;
CommandArgumentData thread_idx_arg;
"thread list",
"Show a summary of all current threads in a process.",
"thread list",
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused )
+ eCommandRequiresProcess |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused )
{
}
"thread info",
"Show an extended summary of information about thread(s) in a process.",
"thread info",
- eFlagRequiresProcess |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused),
+ eCommandRequiresProcess |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused),
m_options (interpreter)
{
m_add_return = false;
"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",
- eFlagRequiresFrame |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresFrame |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_options (interpreter)
{
CommandArgumentEntry arg;
"thread jump",
"Sets the program counter to a new address.",
"thread jump",
- eFlagRequiresFrame |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresFrame |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_options (interpreter)
{
}
"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,
- eFlagRequiresProcess |
- eFlagRequiresThread |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresProcess |
+ eCommandRequiresThread |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_options(interpreter)
{
}
"Only user visible plans can be discarded, use the index from \"thread plan list\""
" without the \"-i\" argument.",
NULL,
- eFlagRequiresProcess |
- eFlagRequiresThread |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused )
+ eCommandRequiresProcess |
+ eCommandRequiresThread |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused )
{
CommandArgumentEntry arg;
CommandArgumentData plan_index_arg;
nullptr,
nullptr,
nullptr,
- eFlagRequiresFrame),
+ eCommandRequiresFrame),
m_formatter_name(formatter_name ? formatter_name : ""),
m_discovery_function(discovery_func)
{
"If watchpoint setting fails, consider disable/delete existing ones "
"to free up resources.",
NULL,
- eFlagRequiresFrame |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresFrame |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_option_group (interpreter),
m_option_watchpoint ()
{
"If watchpoint setting fails, consider disable/delete existing ones "
"to free up resources.",
NULL,
- eFlagRequiresFrame |
- eFlagTryTargetAPILock |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused ),
+ eCommandRequiresFrame |
+ eCommandTryTargetAPILock |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused ),
m_option_group (interpreter),
m_option_watchpoint ()
{
m_exe_ctx = m_interpreter.GetExecutionContext();
const uint32_t flags = GetFlags().Get();
- if (flags & (eFlagRequiresTarget |
- eFlagRequiresProcess |
- eFlagRequiresThread |
- eFlagRequiresFrame |
- eFlagTryTargetAPILock ))
+ if (flags & (eCommandRequiresTarget |
+ eCommandRequiresProcess |
+ eCommandRequiresThread |
+ eCommandRequiresFrame |
+ eCommandTryTargetAPILock ))
{
- if ((flags & eFlagRequiresTarget) && !m_exe_ctx.HasTargetScope())
+ if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope())
{
result.AppendError (GetInvalidTargetDescription());
return false;
}
- if ((flags & eFlagRequiresProcess) && !m_exe_ctx.HasProcessScope())
+ if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope())
{
if (!m_exe_ctx.HasTargetScope())
result.AppendError (GetInvalidTargetDescription());
return false;
}
- if ((flags & eFlagRequiresThread) && !m_exe_ctx.HasThreadScope())
+ if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope())
{
if (!m_exe_ctx.HasTargetScope())
result.AppendError (GetInvalidTargetDescription());
return false;
}
- if ((flags & eFlagRequiresFrame) && !m_exe_ctx.HasFrameScope())
+ if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope())
{
if (!m_exe_ctx.HasTargetScope())
result.AppendError (GetInvalidTargetDescription());
return false;
}
- if ((flags & eFlagRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
+ if ((flags & eCommandRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
{
result.AppendError (GetInvalidRegContextDescription());
return false;
}
- if (flags & eFlagTryTargetAPILock)
+ if (flags & eCommandTryTargetAPILock)
{
Target *target = m_exe_ctx.GetTargetPtr();
if (target)
}
}
- if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
+ if (GetFlags().AnySet (eCommandProcessMustBeLaunched | eCommandProcessMustBePaused))
{
Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
if (process == nullptr)
{
// A process that is not running is considered paused.
- if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
+ if (GetFlags().Test(eCommandProcessMustBeLaunched))
{
result.AppendError ("Process must exist.");
result.SetStatus (eReturnStatusFailed);
case eStateDetached:
case eStateExited:
case eStateUnloaded:
- if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
+ if (GetFlags().Test(eCommandProcessMustBeLaunched))
{
result.AppendError ("Process must be launched.");
result.SetStatus (eReturnStatusFailed);
case eStateRunning:
case eStateStepping:
- if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused))
+ if (GetFlags().Test(eCommandProcessMustBePaused))
{
result.AppendError ("Process is running. Use 'process interrupt' to pause execution.");
result.SetStatus (eReturnStatusFailed);
return got_string;
}
+uint32_t
+ScriptInterpreterPython::GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp)
+{
+ uint32_t result = 0;
+
+ Locker py_lock (this,
+ Locker::AcquireLock | Locker::NoSTDIN,
+ Locker::FreeLock);
+
+ static char callee_name[] = "get_flags";
+
+ if (!cmd_obj_sp)
+ return result;
+
+ PyObject* implementor = (PyObject*)cmd_obj_sp->GetValue();
+
+ if (implementor == nullptr || implementor == Py_None)
+ return result;
+
+ PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ if (pmeth == nullptr || pmeth == Py_None)
+ {
+ Py_XDECREF(pmeth);
+ return result;
+ }
+
+ if (PyCallable_Check(pmeth) == 0)
+ {
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+ return result;
+ }
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+
+ // right now we know this function exists and is callable..
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ if (py_return != nullptr && py_return != Py_None)
+ {
+ if (PyInt_Check(py_return))
+ result = (uint32_t)PyInt_AsLong(py_return);
+ else if (PyLong_Check(py_return))
+ result = (uint32_t)PyLong_AsLong(py_return);
+ }
+ Py_XDECREF(py_return);
+
+ return result;
+}
+
bool
ScriptInterpreterPython::GetLongHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
std::string& dest)
"dump",
"Dump information on Objective-C classes known to the current process.",
"language objc class-table dump",
- eFlagRequiresProcess |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused )
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused )
{
}
"info",
"Dump information on a tagged pointer.",
"language objc tagged-pointer info",
- eFlagRequiresProcess |
- eFlagProcessMustBeLaunched |
- eFlagProcessMustBePaused )
+ eCommandRequiresProcess |
+ eCommandProcessMustBeLaunched |
+ eCommandProcessMustBePaused )
{
CommandArgumentEntry arg;
CommandArgumentData index_arg;
: CommandObjectParsed(interpreter, "renderscript module probe",
"Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
"renderscript module probe",
- eFlagRequiresTarget | eFlagRequiresProcess | eFlagProcessMustBeLaunched)
+ eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript module dump",
"Dumps renderscript specific information for all modules.", "renderscript module dump",
- eFlagRequiresProcess | eFlagProcessMustBeLaunched)
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
self.pycmd_tests ()
def pycmd_tests (self):
+ self.runCmd("command source py_import")
+
+ self.expect('targetname',
+ substrs = ['a.out'], matching=False, error=True)
+
exe = os.path.join (os.getcwd(), "a.out")
self.expect("file " + exe,
patterns = [ "Current executable set to .*a.out" ])
- self.runCmd("command source py_import")
+ self.expect('targetname',
+ substrs = ['a.out'], matching=True, error=False)
# This is the function to remove the custom commands in order to have a
# clean slate for the next test case.
self.expect('welcome Enrico', matching=False, error=True,
substrs = ['Hello Enrico, welcome to LLDB']);
- self.expect('targetname',
- substrs = ['a.out'])
-
self.expect('targetname fail', error=True,
substrs = ['a test for error in command'])
self.runCmd('command script add my_command --class welcome.WelcomeCommand')
self.expect('my_command Blah', substrs = ['Hello Blah, welcome to LLDB'])
- self.runCmd('command script add my_command --function welcome.target_name_impl')
+ self.runCmd('command script add my_command --class welcome.TargetnameCommand')
self.expect('my_command', substrs = ['a.out'])
self.runCmd("command script clear")
script import welcome
script import bug11569
command script add welcome --class welcome.WelcomeCommand
-command script add targetname --function welcome.target_name_impl
+command script add targetname --class welcome.TargetnameCommand
command script add longwait --function welcome.print_wait_impl
command script import mysto.py --allow-reload
command script add tell_sync --function welcome.check_for_synchro --synchronicity sync
-import sys
+import lldb, sys
class WelcomeCommand(object):
def __init__(self, debugger, session_dict):
print >>result, ('Hello ' + args + ', welcome to LLDB');
return None;
-def target_name_impl(debugger, args, result, dict):
- target = debugger.GetSelectedTarget()
- file = target.GetExecutable()
- print >>result, ('Current target ' + file.GetFilename())
- if args == 'fail':
- result.SetError('a test for error in command')
+class TargetnameCommand(object):
+ def __init__(self, debugger, session_dict):
+ pass
+
+ def __call__(self, debugger, args, exe_ctx, result):
+ target = debugger.GetSelectedTarget()
+ file = target.GetExecutable()
+ print >>result, ('Current target ' + file.GetFilename())
+ if args == 'fail':
+ result.SetError('a test for error in command')
+
+ def get_flags(self):
+ return lldb.eCommandRequiresTarget
def print_wait_impl(debugger, args, result, dict):
result.SetImmediateOutputFile(sys.stdout)