summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Target/Thread.h3
-rw-r--r--lldb/source/Commands/CommandObjectArgs.cpp2
-rw-r--r--lldb/source/Commands/CommandObjectFrame.cpp171
-rw-r--r--lldb/source/Target/Thread.cpp7
-rw-r--r--lldb/test/signal/Makefile5
-rw-r--r--lldb/test/signal/main.c25
6 files changed, 175 insertions, 38 deletions
diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h
index 9d04f1dacad..80b86d16753 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -262,6 +262,9 @@ public:
virtual lldb::StackFrameSP
GetStackFrameAtIndex (uint32_t idx);
+ uint32_t
+ GetSelectedFrameIndex ();
+
lldb::StackFrameSP
GetSelectedFrame ();
diff --git a/lldb/source/Commands/CommandObjectArgs.cpp b/lldb/source/Commands/CommandObjectArgs.cpp
index 2df78a4957f..fd57df649af 100644
--- a/lldb/source/Commands/CommandObjectArgs.cpp
+++ b/lldb/source/Commands/CommandObjectArgs.cpp
@@ -37,7 +37,7 @@ using namespace lldb_private;
//
CommandObjectArgs::CommandOptions::CommandOptions () :
-Options()
+ Options()
{
// Keep only one place to reset the values to their defaults
ResetOptionValues();
diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp
index ae1cad4eaa1..20725a68da5 100644
--- a/lldb/source/Commands/CommandObjectFrame.cpp
+++ b/lldb/source/Commands/CommandObjectFrame.cpp
@@ -94,6 +94,62 @@ class CommandObjectFrameSelect : public CommandObject
{
public:
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions () :
+ Options()
+ {
+ ResetOptionValues ();
+ }
+
+ virtual
+ ~CommandOptions ()
+ {
+ }
+
+ virtual Error
+ SetOptionValue (int option_idx, const char *option_arg)
+ {
+ Error error;
+ bool success = false;
+ char short_option = (char) m_getopt_table[option_idx].val;
+ switch (short_option)
+ {
+ case 'r':
+ relative_frame_offset = Args::StringToSInt32 (option_arg, INT32_MIN, 0, &success);
+ if (!success)
+ error.SetErrorStringWithFormat ("invalid frame offset argument '%s'.\n", option_arg);
+ break;
+
+ default:
+ ("Invalid short option character '%c'.\n", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ ResetOptionValues ()
+ {
+ Options::ResetOptionValues();
+ relative_frame_offset = INT32_MIN;
+ }
+
+ const lldb::OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static lldb::OptionDefinition g_option_table[];
+ int32_t relative_frame_offset;
+ };
+
CommandObjectFrameSelect (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"frame select",
@@ -106,7 +162,7 @@ public:
// Define the first (and only) variant of this arg.
index_arg.arg_type = eArgTypeFrameIndex;
- index_arg.arg_repetition = eArgRepeatPlain;
+ index_arg.arg_repetition = eArgRepeatOptional;
// There is only one variant this argument could be; put it into the argument entry.
arg.push_back (index_arg);
@@ -119,6 +175,14 @@ public:
{
}
+ virtual
+ Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
+
bool
Execute (Args& command,
CommandReturnObject &result)
@@ -126,50 +190,73 @@ public:
ExecutionContext exe_ctx (m_interpreter.GetDebugger().GetExecutionContext());
if (exe_ctx.thread)
{
- if (command.GetArgumentCount() == 1)
+ const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
+ uint32_t frame_idx = UINT32_MAX;
+ if (m_options.relative_frame_offset != INT32_MIN)
{
- const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
-
- const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
- const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
- if (frame_idx < num_frames)
+ // The one and only argument is a signed relative frame index
+ frame_idx = exe_ctx.thread->GetSelectedFrameIndex ();
+ if (frame_idx == UINT32_MAX)
+ frame_idx = 0;
+
+ if (m_options.relative_frame_offset < 0)
+ {
+ if (frame_idx >= -m_options.relative_frame_offset)
+ frame_idx += m_options.relative_frame_offset;
+ else
+ frame_idx = 0;
+ }
+ else if (m_options.relative_frame_offset > 0)
+ {
+ if (num_frames - frame_idx > m_options.relative_frame_offset)
+ frame_idx += m_options.relative_frame_offset;
+ else
+ frame_idx = num_frames - 1;
+ }
+ }
+ else
+ {
+ if (command.GetArgumentCount() == 1)
+ {
+ const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
+ frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
+ }
+ else
{
- exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
- exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
+ result.AppendError ("invalid arguments.\n");
+ m_options.GenerateOptionUsage (m_interpreter, result.GetErrorStream(), this);
+ }
+ }
+
+ if (frame_idx < num_frames)
+ {
+ exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
+ exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
- if (exe_ctx.frame)
+ if (exe_ctx.frame)
+ {
+ bool already_shown = false;
+ SymbolContext frame_sc(exe_ctx.frame->GetSymbolContext(eSymbolContextLineEntry));
+ if (m_interpreter.GetDebugger().GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0)
{
- bool already_shown = false;
- SymbolContext frame_sc(exe_ctx.frame->GetSymbolContext(eSymbolContextLineEntry));
- if (m_interpreter.GetDebugger().GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0)
- {
- already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
- }
+ already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
+ }
- if (DisplayFrameForExecutionContext (exe_ctx.thread,
- exe_ctx.frame,
- m_interpreter,
- result.GetOutputStream(),
- true,
- !already_shown,
- 3,
- 3))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return result.Succeeded();
- }
+ if (DisplayFrameForExecutionContext (exe_ctx.thread,
+ exe_ctx.frame,
+ m_interpreter,
+ result.GetOutputStream(),
+ true,
+ !already_shown,
+ 3,
+ 3))
+ {
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ return result.Succeeded();
}
}
- if (frame_idx == UINT32_MAX)
- result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr);
- else
- result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
- }
- else
- {
- result.AppendError ("invalid arguments");
- result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str());
}
+ result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
}
else
{
@@ -178,6 +265,16 @@ public:
result.SetStatus (eReturnStatusFailed);
return false;
}
+protected:
+
+ CommandOptions m_options;
+};
+
+lldb::OptionDefinition
+CommandObjectFrameSelect::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_1, false, "relative", 'r', required_argument, NULL, 0, eArgTypeOffset, "A relative frame index offset from the current frame index."},
+{ 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
};
#pragma mark CommandObjectFrameVariable
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index d45f45ccfd8..60eef83f71d 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -854,6 +854,13 @@ Thread::GetStackFrameAtIndex (uint32_t idx)
return GetStackFrameList().GetFrameAtIndex(idx);
}
+uint32_t
+Thread::GetSelectedFrameIndex ()
+{
+ return GetStackFrameList().GetSelectedFrameIndex();
+}
+
+
lldb::StackFrameSP
Thread::GetSelectedFrame ()
{
diff --git a/lldb/test/signal/Makefile b/lldb/test/signal/Makefile
new file mode 100644
index 00000000000..d6cd0db0506
--- /dev/null
+++ b/lldb/test/signal/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/test/signal/main.c b/lldb/test/signal/main.c
new file mode 100644
index 00000000000..cd7bc0cf2ba
--- /dev/null
+++ b/lldb/test/signal/main.c
@@ -0,0 +1,25 @@
+#include <sys/signal.h>
+
+void handler_usr1 (int i)
+{
+ puts ("got signal usr1");
+}
+
+void handler_alrm (int i)
+{
+ puts ("got signal ALRM");
+}
+
+main ()
+{
+ int i = 0;
+
+ signal (SIGUSR1, handler_usr1);
+ signal (SIGALRM, handler_alrm);
+
+ puts ("Put breakpoint here");
+
+ while (i++ < 20)
+ sleep (1);
+}
+
OpenPOWER on IntegriCloud