blob: e7ab75c3877966fc7c3a0ec28164892cda1ab1f5 [file] [log] [blame]
Chris Lattner7af5c122004-01-05 05:27:31 +00001//===-- CLIDebugger.cpp - Command Line Interface to the Debugger ----------===//
Misha Brukman3da94ae2005-04-22 00:00:37 +00002//
Chris Lattner7af5c122004-01-05 05:27:31 +00003// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukman3da94ae2005-04-22 00:00:37 +00007//
Chris Lattner7af5c122004-01-05 05:27:31 +00008//===----------------------------------------------------------------------===//
Misha Brukman3da94ae2005-04-22 00:00:37 +00009//
Chris Lattner7af5c122004-01-05 05:27:31 +000010// This file contains the main implementation of the Command Line Interface to
11// the debugger.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CLIDebugger.h"
16#include "CLICommand.h"
17#include "llvm/Debugger/SourceFile.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000018#include "llvm/ADT/StringExtras.h"
Chris Lattner7af5c122004-01-05 05:27:31 +000019#include <iostream>
20using namespace llvm;
21
22/// CLIDebugger constructor - This initializes the debugger to its default
23/// state, and initializes the command table.
24///
25CLIDebugger::CLIDebugger()
26 : TheProgramInfo(0), TheRuntimeInfo(0), Prompt("(llvm-db) "), ListSize(10) {
27 // Initialize instance variables
28 CurrentFile = 0;
29 LineListedStart = 1;
30 LineListedEnd = 1;
31 LastCurrentFrame = 0;
32 CurrentLanguage = 0;
33
34 CLICommand *C;
35 //===--------------------------------------------------------------------===//
36 // Program startup and shutdown options
37 //
38 addCommand("file", new BuiltinCLICommand(
39 "Use specified file as the program to be debugged",
40 "The debugger looks in the current directory and the program $PATH for the"
41 " specified LLVM program. It then unloads the currently loaded program and"
42 " loads the specified program.\n",
43 &CLIDebugger::fileCommand));
44
45 addCommand("create", new BuiltinCLICommand(
Chris Lattner8b1125f2004-01-06 05:36:30 +000046 "Start the program, halting its execution in main",
Chris Lattner7af5c122004-01-05 05:27:31 +000047 "This command creates an instance of the current program, but stops"
Chris Lattner8b1125f2004-01-06 05:36:30 +000048 "\nexecution immediately.\n",
Chris Lattner7af5c122004-01-05 05:27:31 +000049 &CLIDebugger::createCommand));
50
51 addCommand("kill", new BuiltinCLICommand(
52 "Kills the execution of the current program being debugged", "",
53 &CLIDebugger::killCommand));
54
55 addCommand("quit", new BuiltinCLICommand(
56 "Exit the debugger", "",
57 &CLIDebugger::quitCommand));
58
59 //===--------------------------------------------------------------------===//
60 // Program execution commands
61 //
62 addCommand("run", C = new BuiltinCLICommand(
63 "Start the program running from the beginning", "",
64 &CLIDebugger::runCommand));
65 addCommand("r", C);
66
67 addCommand("cont", C = new BuiltinCLICommand(
68 "Continue program being debugged until the next stop point", "",
69 &CLIDebugger::contCommand));
70 addCommand("c", C); addCommand("fg", C);
71
72 addCommand("step", C = new BuiltinCLICommand(
73 "Step program until it reaches a new source line", "",
74 &CLIDebugger::stepCommand));
75 addCommand("s", C);
76
77 addCommand("next", C = new BuiltinCLICommand(
78 "Step program until it reaches a new source line, stepping over calls", "",
79 &CLIDebugger::nextCommand));
Misha Brukman3da94ae2005-04-22 00:00:37 +000080 addCommand("n", C);
Chris Lattner7af5c122004-01-05 05:27:31 +000081
82 addCommand("finish", new BuiltinCLICommand(
83 "Execute until the selected stack frame returns",
84 "Upon return, the value returned is printed and put in the value history.\n",
85 &CLIDebugger::finishCommand));
86
87 //===--------------------------------------------------------------------===//
88 // Stack frame commands
89 //
90 addCommand("backtrace", C = new BuiltinCLICommand(
91 "Print backtrace of all stack frames, or innermost COUNT frames",
92 "FIXME: describe. Takes 'n', '-n' or 'full'\n",
93 &CLIDebugger::backtraceCommand));
Misha Brukman3da94ae2005-04-22 00:00:37 +000094 addCommand("bt", C);
95
Chris Lattner7af5c122004-01-05 05:27:31 +000096 addCommand("up", new BuiltinCLICommand(
97 "Select and print stack frame that called this one",
98 "An argument says how many frames up to go.\n",
99 &CLIDebugger::upCommand));
100
101 addCommand("down", new BuiltinCLICommand(
102 "Select and print stack frame called by this one",
103 "An argument says how many frames down go.\n",
104 &CLIDebugger::downCommand));
105
106 addCommand("frame", C = new BuiltinCLICommand(
107 "Select and print a stack frame",
108 "With no argument, print the selected stack frame. (See also 'info frame').\n"
109 "An argument specifies the frame to select.\n",
110 &CLIDebugger::frameCommand));
Misha Brukman3da94ae2005-04-22 00:00:37 +0000111 addCommand("f", C);
Chris Lattner7af5c122004-01-05 05:27:31 +0000112
113 //===--------------------------------------------------------------------===//
114 // Breakpoint related commands
115 //
116 addCommand("break", C = new BuiltinCLICommand(
117 "Set breakpoint at specified line or function",
118 "FIXME: describe.\n",
119 &CLIDebugger::breakCommand));
Misha Brukman3da94ae2005-04-22 00:00:37 +0000120 addCommand("b", C);
Chris Lattner7af5c122004-01-05 05:27:31 +0000121
122
123 //===--------------------------------------------------------------------===//
124 // Miscellaneous commands
125 //
126 addCommand("info", new BuiltinCLICommand(
127 "Generic command for showing things about the program being debugged",
Chris Lattner395236f2004-10-26 05:46:17 +0000128 "info functions: display information about functions in the program.\ninfo"
129 " source : display information about the current source file.\ninfo source"
130 "s : Display source file names for the program\ninfo target : print status"
131 " of inferior process\n",
Chris Lattner7af5c122004-01-05 05:27:31 +0000132 &CLIDebugger::infoCommand));
133
134 addCommand("list", C = new BuiltinCLICommand(
135 "List specified function or line",
136 "FIXME: document\n",
137 &CLIDebugger::listCommand));
138 addCommand("l", C);
139
140 addCommand("set", new BuiltinCLICommand(
141 "Change program or debugger variable",
142 "FIXME: document\n",
143 &CLIDebugger::setCommand));
144
145 addCommand("show", new BuiltinCLICommand(
146 "Generic command for showing things about the debugger",
147 "FIXME: document\n",
148 &CLIDebugger::showCommand));
149
150 addCommand("help", C = new BuiltinCLICommand(
151 "Prints information about available commands", "",
152 &CLIDebugger::helpCommand));
153 addCommand("h", C);
154}
155
156
157/// addCommand - Add a command to the CommandTable, potentially displacing a
158/// preexisting command.
159void CLIDebugger::addCommand(const std::string &Option, CLICommand *Cmd) {
160 assert(Cmd && "Cannot set a null command!");
161 CLICommand *&CS = CommandTable[Option];
162 if (CS == Cmd) return; // noop
163
164 // If we already have a command, decrement the command's reference count.
165 if (CS) {
166 CS->removeOptionName(Option);
167 CS->dropRef();
168 }
169 CS = Cmd;
170
171 // Remember that we are using this command.
172 Cmd->addRef();
173 Cmd->addOptionName(Option);
174}
175
176static bool isValidPrefix(const std::string &Prefix, const std::string &Option){
177 return Prefix.size() <= Option.size() &&
178 Prefix == std::string(Option.begin(), Option.begin()+Prefix.size());
179}
180
181/// getCommand - This looks up the specified command using a fuzzy match.
182/// If the string exactly matches a command or is an unambiguous prefix of a
183/// command, it returns the command. Otherwise it throws an exception
184/// indicating the possible ambiguous choices.
185CLICommand *CLIDebugger::getCommand(const std::string &Command) {
186
187 // Look up the command in the table.
188 std::map<std::string, CLICommand*>::iterator CI =
189 CommandTable.lower_bound(Command);
Misha Brukman3da94ae2005-04-22 00:00:37 +0000190
Chris Lattner7af5c122004-01-05 05:27:31 +0000191 if (Command == "") {
Chris Lattner8b1125f2004-01-06 05:36:30 +0000192 throw "Null command should not get here!";
Chris Lattner7af5c122004-01-05 05:27:31 +0000193 } else if (CI == CommandTable.end() ||
194 !isValidPrefix(Command, CI->first)) {
195 // If this command has no relation to anything in the command table,
196 // print the error message.
197 throw "Unknown command: '" + Command +
198 "'. Use 'help' for list of commands.";
199 } else if (CI->first == Command) {
200 // We have an exact match on the command
201 return CI->second;
202 } else {
203 // Otherwise, we have a prefix match. Check to see if this is
204 // unambiguous, and if so, run it.
205 std::map<std::string, CLICommand*>::iterator CI2 = CI;
206
207 // If the next command is a valid completion of this one, we are
208 // ambiguous.
209 if (++CI2 != CommandTable.end() && isValidPrefix(Command, CI2->first)) {
Misha Brukman3da94ae2005-04-22 00:00:37 +0000210 std::string ErrorMsg =
Chris Lattner7af5c122004-01-05 05:27:31 +0000211 "Ambiguous command '" + Command + "'. Options: " + CI->first;
212 for (++CI; CI != CommandTable.end() &&
213 isValidPrefix(Command, CI->first); ++CI)
214 ErrorMsg += ", " + CI->first;
215 throw ErrorMsg;
216 } else {
217 // It's an unambiguous prefix of a command, use it.
218 return CI->second;
219 }
220 }
221}
222
223
224/// run - Start the debugger, returning when the user exits the debugger. This
225/// starts the main event loop of the CLI debugger.
226///
227int CLIDebugger::run() {
228 std::string Command;
229 std::cout << Prompt;
230
Chris Lattner8b1125f2004-01-06 05:36:30 +0000231 // Keep track of the last command issued, so that we can reissue it if the
232 // user hits enter as the command.
233 CLICommand *LastCommand = 0;
234 std::string LastArgs;
235
Chris Lattner7af5c122004-01-05 05:27:31 +0000236 // Continue reading commands until the end of file.
237 while (getline(std::cin, Command)) {
238 std::string Arguments = Command;
239
240 // Split off the command from the arguments to the command.
241 Command = getToken(Arguments, " \t\n\v\f\r\\/;.*&");
242
243 try {
Chris Lattner8b1125f2004-01-06 05:36:30 +0000244 CLICommand *CurCommand;
Misha Brukman3da94ae2005-04-22 00:00:37 +0000245
Chris Lattner8b1125f2004-01-06 05:36:30 +0000246 if (Command == "") {
247 CurCommand = LastCommand;
248 Arguments = LastArgs;
249 } else {
250 CurCommand = getCommand(Command);
251 }
252
253 // Save the command we are running in case the user wants us to repeat it
254 // next time.
255 LastCommand = CurCommand;
256 LastArgs = Arguments;
257
258 // Finally, execute the command.
259 if (CurCommand)
Misha Brukman3da94ae2005-04-22 00:00:37 +0000260 CurCommand->runCommand(*this, Arguments);
Chris Lattner7af5c122004-01-05 05:27:31 +0000261
262 } catch (int RetVal) {
263 // The quit command exits the command loop by throwing an integer return
264 // code.
265 return RetVal;
266 } catch (const std::string &Error) {
267 std::cout << "Error: " << Error << "\n";
268 } catch (const char *Error) {
269 std::cout << "Error: " << Error << "\n";
270 } catch (const NonErrorException &E) {
271 std::cout << E.getMessage() << "\n";
272 } catch (...) {
273 std::cout << "ERROR: Debugger caught unexpected exception!\n";
274 // Attempt to continue.
275 }
Misha Brukman3da94ae2005-04-22 00:00:37 +0000276
Chris Lattner7af5c122004-01-05 05:27:31 +0000277 // Write the prompt to get the next bit of user input
278 std::cout << Prompt;
279 }
280
281 return 0;
282}
283
284
285/// askYesNo - Ask the user a question, and demand a yes/no response. If
286/// the user says yes, return true.
287///
288bool CLIDebugger::askYesNo(const std::string &Message) const {
289 std::string Answer;
290 std::cout << Message << " (y or n) " << std::flush;
291 while (getline(std::cin, Answer)) {
292 std::string Val = getToken(Answer);
293 if (getToken(Answer).empty()) {
294 if (Val == "yes" || Val == "y" || Val == "YES" || Val == "Y" ||
295 Val == "Yes")
296 return true;
297 if (Val == "no" || Val == "n" || Val == "NO" || Val == "N" ||
298 Val == "No")
299 return false;
300 }
301
302 std::cout << "Please answer y or n.\n" << Message << " (y or n) "
303 << std::flush;
304 }
Misha Brukman3da94ae2005-04-22 00:00:37 +0000305
Chris Lattner7af5c122004-01-05 05:27:31 +0000306 // Ran out of input?
307 return false;
308}