xref: /llvm-project/lldb/source/Commands/CommandObjectFrame.cpp (revision e40e42181fcc0c9742d6fcb654b0e1dee07a2513)
1 //===-- CommandObjectFrame.cpp ----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CommandObjectFrame.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Interpreter/Args.h"
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/Timer.h"
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 #include "lldb/Interpreter/CommandReturnObject.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/StackFrame.h"
24 #include "lldb/Target/Thread.h"
25 
26 #include "CommandObjectThread.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 #pragma mark CommandObjectFrameInfo
32 
33 //-------------------------------------------------------------------------
34 // CommandObjectFrameInfo
35 //-------------------------------------------------------------------------
36 
37 class CommandObjectFrameInfo : public CommandObject
38 {
39 public:
40 
41     CommandObjectFrameInfo () :
42     CommandObject ("frame info",
43                    "Lists information about the currently selected frame in the current thread.",
44                    "frame info",
45                    eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
46     {
47     }
48 
49     ~CommandObjectFrameInfo ()
50     {
51     }
52 
53     bool
54     Execute (CommandInterpreter &interpreter,
55              Args& command,
56              CommandReturnObject &result)
57     {
58         ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
59         if (exe_ctx.frame)
60         {
61             exe_ctx.frame->Dump (&result.GetOutputStream(), true);
62             result.GetOutputStream().EOL();
63             result.SetStatus (eReturnStatusSuccessFinishResult);
64         }
65         else
66         {
67             result.AppendError ("no current frame");
68             result.SetStatus (eReturnStatusFailed);
69         }
70         return result.Succeeded();
71     }
72 };
73 
74 #pragma mark CommandObjectFrameSelect
75 
76 //-------------------------------------------------------------------------
77 // CommandObjectFrameSelect
78 //-------------------------------------------------------------------------
79 
80 class CommandObjectFrameSelect : public CommandObject
81 {
82 public:
83 
84     CommandObjectFrameSelect () :
85     CommandObject ("frame select",
86                    "Select the current frame by index in the current thread.",
87                    "frame select <frame-index>",
88                    eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
89     {
90     }
91 
92     ~CommandObjectFrameSelect ()
93     {
94     }
95 
96     bool
97     Execute (CommandInterpreter &interpreter,
98              Args& command,
99              CommandReturnObject &result)
100     {
101         ExecutionContext exe_ctx (interpreter.GetDebugger().GetExecutionContext());
102         if (exe_ctx.thread)
103         {
104             if (command.GetArgumentCount() == 1)
105             {
106                 const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
107 
108                 const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
109                 const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
110                 if (frame_idx < num_frames)
111                 {
112                     exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
113                     exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
114 
115                     if (exe_ctx.frame)
116                     {
117                         bool already_shown = false;
118                         SymbolContext frame_sc(exe_ctx.frame->GetSymbolContext(eSymbolContextLineEntry));
119                         if (interpreter.GetDebugger().UseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0)
120                         {
121                             already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
122                         }
123 
124                         if (DisplayFrameForExecutionContext (exe_ctx.thread,
125                                                              exe_ctx.frame,
126                                                              interpreter,
127                                                              result.GetOutputStream(),
128                                                              true,
129                                                              !already_shown,
130                                                              3,
131                                                              3))
132                         {
133                             result.SetStatus (eReturnStatusSuccessFinishResult);
134                             return result.Succeeded();
135                         }
136                     }
137                 }
138                 if (frame_idx == UINT32_MAX)
139                     result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr);
140                 else
141                     result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
142             }
143             else
144             {
145                 result.AppendError ("invalid arguments");
146                 result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str());
147             }
148         }
149         else
150         {
151             result.AppendError ("no current thread");
152         }
153         result.SetStatus (eReturnStatusFailed);
154         return false;
155     }
156 };
157 
158 #pragma mark CommandObjectMultiwordFrame
159 
160 //-------------------------------------------------------------------------
161 // CommandObjectMultiwordFrame
162 //-------------------------------------------------------------------------
163 
164 CommandObjectMultiwordFrame::CommandObjectMultiwordFrame (CommandInterpreter &interpreter) :
165     CommandObjectMultiword ("frame",
166                             "A set of commands for operating on the current thread's frames.",
167                             "frame <subcommand> [<subcommand-options>]")
168 {
169     LoadSubCommand (interpreter, "info",   CommandObjectSP (new CommandObjectFrameInfo ()));
170     LoadSubCommand (interpreter, "select", CommandObjectSP (new CommandObjectFrameSelect ()));
171 }
172 
173 CommandObjectMultiwordFrame::~CommandObjectMultiwordFrame ()
174 {
175 }
176 
177