Added a new test case to test signals with.

Added frame relative frame selection to "frame select". You can now select
frames relative to the current frame (which defaults to zero if the current
frame hasn't yet been set for a thread):

The gdb "up" command can be done as:
(lldb) frame select -r 1
The gdb "down" command can be done as:
(lldb) frame select -r -1

Place the following in your ~/.lldbinit file for "up" and "down":

command alias up frame select -r 1
command alias down frame select -r -1

llvm-svn: 116176
This commit is contained in:
Greg Clayton
2010-10-10 22:28:11 +00:00
parent 222f5700c2
commit 864174e100
6 changed files with 175 additions and 38 deletions

View File

@@ -262,6 +262,9 @@ public:
virtual lldb::StackFrameSP
GetStackFrameAtIndex (uint32_t idx);
uint32_t
GetSelectedFrameIndex ();
lldb::StackFrameSP
GetSelectedFrame ();

View File

@@ -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();

View File

@@ -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)
{
exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
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
{
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

View File

@@ -854,6 +854,13 @@ Thread::GetStackFrameAtIndex (uint32_t idx)
return GetStackFrameList().GetFrameAtIndex(idx);
}
uint32_t
Thread::GetSelectedFrameIndex ()
{
return GetStackFrameList().GetSelectedFrameIndex();
}
lldb::StackFrameSP
Thread::GetSelectedFrame ()
{

View File

@@ -0,0 +1,5 @@
LEVEL = ../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

25
lldb/test/signal/main.c Normal file
View File

@@ -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);
}