[Lldb-commits] [lldb] r116430 - in /lldb/trunk: include/lldb/lldb-enumerations.h source/Commands/CommandObjectProcess.cpp source/Interpreter/CommandObject.cpp source/Target/Process.cpp

Caroline Tice ctice at apple.com
Wed Oct 13 13:44:39 PDT 2010


Author: ctice
Date: Wed Oct 13 15:44:39 2010
New Revision: 116430

URL: http://llvm.org/viewvc/llvm-project?rev=116430&view=rev
Log:
Add new argument type, eArgSignalName,

Add missing break statment to case statement in Process::ShouldBroadcastEvent.

Add new command, "process handle" to allow users to control process behavior on
the receipt of various Unix signals (whether the process should stop; whether the
process should be passed the signal; whether the debugger user should be notified
that the signal came in).



Modified:
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/source/Commands/CommandObjectProcess.cpp
    lldb/trunk/source/Interpreter/CommandObject.cpp
    lldb/trunk/source/Target/Process.cpp

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=116430&r1=116429&r2=116430&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Wed Oct 13 15:44:39 2010
@@ -558,6 +558,7 @@
     eArgTypeSettingKey,
     eArgTypeSettingPrefix,
     eArgTypeSettingVariableName,
+    eArgTypeSignalName,
     eArgTypeShlibName,
     eArgTypeSourceFile,
     eArgTypeSortOrder,

Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=116430&r1=116429&r2=116430&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Wed Oct 13 15:44:39 2010
@@ -1080,6 +1080,245 @@
 };
 
 //-------------------------------------------------------------------------
+// CommandObjectProcessHandle
+//-------------------------------------------------------------------------
+
+class CommandObjectProcessHandle : public CommandObject
+{
+public:
+
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions () :
+            Options ()
+        {
+            ResetOptionValues ();
+        }
+
+        ~CommandOptions ()
+        {
+        }
+
+        Error
+        SetOptionValue (int option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            
+            switch (short_option)
+            {
+                case 's':
+                    stop = option_arg;
+                    break;
+                case 'n':
+                    notify = option_arg;
+                    break;
+                case 'p':
+                    pass = option_arg;
+                    break;
+                default:
+                    error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
+                    break;
+            }
+            return error;
+        }
+
+        void
+        ResetOptionValues ()
+        {
+            Options::ResetOptionValues();
+            stop.clear();
+            notify.clear();
+            pass.clear();
+        }
+
+        const lldb::OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+
+        // Options table: Required for subclasses of Options.
+
+        static lldb::OptionDefinition g_option_table[];
+
+        // Instance variables to hold the values for command options.
+
+        std::string stop;
+        std::string notify;
+        std::string pass;
+    };
+
+
+    CommandObjectProcessHandle (CommandInterpreter &interpreter) :
+        CommandObject (interpreter,
+                       "process handle",
+                       "Update whether the process should or should not stop or notify or suppress various signals it receives from the OS.",
+                       NULL)
+    {
+        CommandArgumentEntry arg;
+        CommandArgumentData signal_name_arg;
+
+        signal_name_arg.arg_type = eArgTypeSignalName;
+        signal_name_arg.arg_repetition = eArgRepeatPlus;
+
+        arg.push_back (signal_name_arg);
+        
+        m_arguments.push_back (arg);
+    }
+
+    ~CommandObjectProcessHandle ()
+    {
+    }
+
+    Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+
+    bool
+    VerifyCommandOptionValue (const std::string &option, int *real_value)
+    {
+        bool okay = true;
+
+        if (strcasecmp (option.c_str(), "false") == 0)
+            *real_value = 0;
+        else if (strcasecmp (option.c_str(), "true") == 0)
+            *real_value = 1;
+        else
+        {
+            // If the value isn't 'true' or 'false', it had better be 0 or 1.
+            *real_value = Args::StringToUInt32 (option.c_str(), 3);
+            if (*real_value != 0 && *real_value != 1)
+                okay = false;
+        }
+        
+        return okay;
+    }
+
+    bool
+    Execute (Args &signal_args, CommandReturnObject &result)
+    {
+        TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
+        
+        if (!target_sp)
+        {
+            result.AppendError ("No current target;"
+                                " cannot handle signals until you have a valid target and process.\n");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+        
+        ProcessSP process_sp = target_sp->GetProcessSP();
+
+        if (!process_sp)
+        {
+            result.AppendError ("No current process; cannot handle signals until you have a valid process.\n");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        if (m_options.stop.empty()
+            && m_options.notify.empty()
+            && m_options.pass.empty())
+        {
+            result.AppendError ("No action specified (-s or -n or -q); no signal will be updated.\n");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        size_t num_signals = signal_args.GetArgumentCount();
+        if (num_signals == 0)
+        {
+            result.AppendError ("No signal specified to be updated.\n");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        int stop_action = -1;   // -1 means leave the current setting alone
+        int pass_action = -1;  // -1 means leave the current setting alone
+        int notify_action = -1; // -1 means leave the current setting alone
+
+        if (! m_options.stop.empty()
+            && ! VerifyCommandOptionValue (m_options.stop, &stop_action))
+        {
+            result.AppendError ("Invalid argument for command option --stop; must be true or false.\n");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        if (! m_options.notify.empty()
+            && ! VerifyCommandOptionValue (m_options.notify, &notify_action))
+        {
+            result.AppendError ("Invalid argument for command option --notify; must be true or false.\n");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        if (! m_options.pass.empty()
+            && ! VerifyCommandOptionValue (m_options.pass, &pass_action))
+        {
+            result.AppendError ("Invalid argument for command option --pass; must be true or false.\n");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        size_t num_args = signal_args.GetArgumentCount();
+        UnixSignals &signals = process_sp->GetUnixSignals();
+        int num_signals_set = 0;
+
+        for (size_t i = 0; i < num_args; ++i)
+        {
+            int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i));
+            if (signo != LLDB_INVALID_SIGNAL_NUMBER)
+            {
+                // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees that
+                // the value is either 0 or 1.
+                if (stop_action != -1)
+                    signals.SetShouldStop (signo, (bool) stop_action);
+                if (pass_action != -1)
+                {
+                    if (pass_action == 1) // pass it down, so 'suppress' is false
+                        signals.SetShouldSuppress (signo, false);
+                    else if (pass_action == 0) // do not pass it down, so 'suppress' is true
+                        signals.SetShouldSuppress (signo, true);
+                }
+                if (notify_action != -1)
+                    signals.SetShouldNotify (signo, (bool) notify_action);
+                ++num_signals_set;
+            }
+            else
+            {
+                result.AppendErrorWithFormat ("Invalid signal name '%s'\n", signal_args.GetArgumentAtIndex (i));
+            }
+        }
+
+        if (num_signals_set > 0)
+            result.SetStatus (eReturnStatusSuccessFinishNoResult);
+        else
+            result.SetStatus (eReturnStatusFailed);
+
+        return result.Succeeded();
+    }
+
+protected:
+
+    CommandOptions m_options;
+};
+
+lldb::OptionDefinition
+CommandObjectProcessHandle::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_1, false, "stop",   's', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." },
+{ LLDB_OPT_SET_1, false, "notify", 'n', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." },
+{ LLDB_OPT_SET_1, false, "pass",  'p', required_argument, NULL, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." },
+{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+//-------------------------------------------------------------------------
 // CommandObjectMultiwordProcess
 //-------------------------------------------------------------------------
 
@@ -1094,6 +1333,7 @@
     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
+    LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus (interpreter)));
     LoadSubCommand ("interrupt",   CommandObjectSP (new CommandObjectProcessInterrupt (interpreter)));
     LoadSubCommand ("kill",        CommandObjectSP (new CommandObjectProcessKill (interpreter)));

Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=116430&r1=116429&r2=116430&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Wed Oct 13 15:44:39 2010
@@ -647,6 +647,7 @@
     { eArgTypeSettingKey, "setting-key", CommandCompletions::eNoCompletion, NULL, "A key into a settings variables that is a dictionary (try 'settings list' to see all the possible settings variables and their types)." },
     { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, NULL, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" },
     { eArgTypeSettingVariableName, "setting-variable-name", CommandCompletions::eNoCompletion, NULL, "The name of a settable internal debugger variable.  Type 'settings list' to see a complete list of such variables." },
+    { eArgTypeSignalName, "signal-name", CommandCompletions::eNoCompletion, NULL, "The name of a UNIX signal (e.g. SIGINT or SIGKILL) ." },
     { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, NULL, "The name of a shared library." },
     { eArgTypeSourceFile, "source-file", CommandCompletions::eNoCompletion, NULL, "The name of a source file.." },
     { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, NULL, "Specify a sort order when dumping lists." },

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=116430&r1=116429&r2=116430&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Wed Oct 13 15:44:39 2010
@@ -1439,6 +1439,7 @@
                     {
                         case eVoteYes:
                             Process::ProcessEventData::SetRestartedInEvent (event_ptr, true);
+                            break;
                         case eVoteNoOpinion:
                         case eVoteNo:
                             return_value = false;





More information about the lldb-commits mailing list