mirror of
https://github.com/intel/llvm.git
synced 2026-01-17 06:40:01 +08:00
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:
@@ -262,6 +262,9 @@ public:
|
||||
virtual lldb::StackFrameSP
|
||||
GetStackFrameAtIndex (uint32_t idx);
|
||||
|
||||
uint32_t
|
||||
GetSelectedFrameIndex ();
|
||||
|
||||
lldb::StackFrameSP
|
||||
GetSelectedFrame ();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -854,6 +854,13 @@ Thread::GetStackFrameAtIndex (uint32_t idx)
|
||||
return GetStackFrameList().GetFrameAtIndex(idx);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Thread::GetSelectedFrameIndex ()
|
||||
{
|
||||
return GetStackFrameList().GetSelectedFrameIndex();
|
||||
}
|
||||
|
||||
|
||||
lldb::StackFrameSP
|
||||
Thread::GetSelectedFrame ()
|
||||
{
|
||||
|
||||
5
lldb/test/signal/Makefile
Normal file
5
lldb/test/signal/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
LEVEL = ../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
25
lldb/test/signal/main.c
Normal file
25
lldb/test/signal/main.c
Normal 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user