blob: 613a19d2f3fa050e0363e0f60cd051e69f53aca0 [file] [log] [blame]
Chris Lattner2eacf262004-01-05 05:25:10 +00001//===-- Debugger.cpp - LLVM debugger library implementation ---------------===//
Misha Brukmanedf128a2005-04-21 22:36:52 +00002//
Chris Lattner2eacf262004-01-05 05:25:10 +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 Brukmanedf128a2005-04-21 22:36:52 +00007//
Chris Lattner2eacf262004-01-05 05:25:10 +00008//===----------------------------------------------------------------------===//
Misha Brukmanedf128a2005-04-21 22:36:52 +00009//
Chris Lattner2eacf262004-01-05 05:25:10 +000010// This file contains the main implementation of the LLVM debugger library.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Debugger/Debugger.h"
15#include "llvm/Module.h"
16#include "llvm/ModuleProvider.h"
17#include "llvm/Bytecode/Reader.h"
18#include "llvm/Debugger/InferiorProcess.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000019#include "llvm/ADT/StringExtras.h"
Duraid Madina4547e222005-12-26 10:24:15 +000020#include <memory>
Chris Lattner2eacf262004-01-05 05:25:10 +000021using namespace llvm;
22
23/// Debugger constructor - Initialize the debugger to its initial, empty, state.
24///
25Debugger::Debugger() : Environment(0), Program(0), Process(0) {
26}
27
28Debugger::~Debugger() {
29 // Killing the program could throw an exception. We don't want to progagate
30 // the exception out of our destructor though.
31 try {
32 killProgram();
33 } catch (const char *) {
34 } catch (const std::string &) {
35 }
Misha Brukmanedf128a2005-04-21 22:36:52 +000036
Chris Lattner2eacf262004-01-05 05:25:10 +000037 unloadProgram();
38}
39
40/// getProgramPath - Get the path of the currently loaded program, or an
41/// empty string if none is loaded.
42std::string Debugger::getProgramPath() const {
43 return Program ? Program->getModuleIdentifier() : "";
44}
45
46static Module *
47getMaterializedModuleProvider(const std::string &Filename) {
Reid Spencer0b5a5042006-08-25 17:43:11 +000048 return ParseBytecodeFile(Filename);
Chris Lattner2eacf262004-01-05 05:25:10 +000049}
50
51/// loadProgram - If a program is currently loaded, unload it. Then search
52/// the PATH for the specified program, loading it when found. If the
53/// specified program cannot be found, an exception is thrown to indicate the
54/// error.
55void Debugger::loadProgram(const std::string &Filename) {
56 if ((Program = getMaterializedModuleProvider(Filename)) ||
57 (Program = getMaterializedModuleProvider(Filename+".bc")))
58 return; // Successfully loaded the program.
59
60 // Search the program path for the file...
61 if (const char *PathS = getenv("PATH")) {
62 std::string Path = PathS;
63
64 std::string Directory = getToken(Path, ":");
65 while (!Directory.empty()) {
66 if ((Program = getMaterializedModuleProvider(Directory +"/"+ Filename)) ||
67 (Program = getMaterializedModuleProvider(Directory +"/"+ Filename
68 + ".bc")))
69 return; // Successfully loaded the program.
70
71 Directory = getToken(Path, ":");
72 }
73 }
74
75 throw "Could not find program '" + Filename + "'!";
76}
77
78/// unloadProgram - If a program is running, kill it, then unload all traces
79/// of the current program. If no program is loaded, this method silently
80/// succeeds.
81void Debugger::unloadProgram() {
82 if (!isProgramLoaded()) return;
83 killProgram();
84 delete Program;
85 Program = 0;
86}
87
88
89/// createProgram - Create an instance of the currently loaded program,
90/// killing off any existing one. This creates the program and stops it at
91/// the first possible moment. If there is no program loaded or if there is a
92/// problem starting the program, this method throws an exception.
93void Debugger::createProgram() {
94 if (!isProgramLoaded())
95 throw "Cannot start program: none is loaded.";
96
97 // Kill any existing program.
98 killProgram();
99
100 // Add argv[0] to the arguments vector..
101 std::vector<std::string> Args(ProgramArguments);
102 Args.insert(Args.begin(), getProgramPath());
103
104 // Start the new program... this could throw if the program cannot be started.
105 Process = InferiorProcess::create(Program, Args, Environment);
106}
107
Chris Lattner89b19262006-03-10 22:39:48 +0000108InferiorProcess *
109InferiorProcess::create(Module *M, const std::vector<std::string> &Arguments,
110 const char * const *envp) {
111 throw"No supported binding to inferior processes (debugger not implemented).";
112}
113
Chris Lattner2eacf262004-01-05 05:25:10 +0000114/// killProgram - If the program is currently executing, kill off the
115/// process and free up any state related to the currently running program. If
116/// there is no program currently running, this just silently succeeds.
117void Debugger::killProgram() {
118 // The destructor takes care of the dirty work.
Chris Lattnerde31b762004-01-14 20:58:17 +0000119 try {
120 delete Process;
121 } catch (...) {
122 Process = 0;
123 throw;
124 }
Chris Lattner2eacf262004-01-05 05:25:10 +0000125 Process = 0;
126}
127
128/// stepProgram - Implement the 'step' command, continuing execution until
129/// the next possible stop point.
130void Debugger::stepProgram() {
131 assert(isProgramRunning() && "Cannot step if the program isn't running!");
132 try {
133 Process->stepProgram();
134 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000135 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000136 throw NonErrorException("The program stopped with exit code " +
137 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000138 } catch (...) {
139 killProgram();
140 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000141 }
142}
143
144/// nextProgram - Implement the 'next' command, continuing execution until
145/// the next possible stop point that is in the current function.
146void Debugger::nextProgram() {
147 assert(isProgramRunning() && "Cannot next if the program isn't running!");
148 try {
149 // This should step the process. If the process enters a function, then it
150 // should 'finish' it. However, figuring this out is tricky. In
151 // particular, the program can do any of:
152 // 0. Not change current frame.
153 // 1. Entering or exiting a region within the current function
154 // (which changes the frame ID, but which we shouldn't 'finish')
155 // 2. Exiting the current function (which changes the frame ID)
156 // 3. Entering a function (which should be 'finish'ed)
157 // For this reason, we have to be very careful about when we decide to do
158 // the 'finish'.
159
160 // Get the current frame, but don't trust it. It could change...
161 void *CurrentFrame = Process->getPreviousFrame(0);
162
163 // Don't trust the current frame: get the caller frame.
164 void *ParentFrame = Process->getPreviousFrame(CurrentFrame);
Misha Brukmanedf128a2005-04-21 22:36:52 +0000165
Chris Lattner2eacf262004-01-05 05:25:10 +0000166 // Ok, we have some information, run the program one step.
167 Process->stepProgram();
168
169 // Where is the new frame? The most common case, by far is that it has not
170 // been modified (Case #0), in which case we don't need to do anything more.
171 void *NewFrame = Process->getPreviousFrame(0);
172 if (NewFrame != CurrentFrame) {
173 // Ok, the frame changed. If we are case #1, then the parent frame will
174 // be identical.
175 void *NewParentFrame = Process->getPreviousFrame(NewFrame);
176 if (ParentFrame != NewParentFrame) {
177 // Ok, now we know we aren't case #0 or #1. Check to see if we entered
178 // a new function. If so, the parent frame will be "CurrentFrame".
179 if (CurrentFrame == NewParentFrame)
180 Process->finishProgram(NewFrame);
181 }
182 }
183
184 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000185 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000186 throw NonErrorException("The program stopped with exit code " +
187 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000188 } catch (...) {
189 killProgram();
190 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000191 }
192}
193
194/// finishProgram - Implement the 'finish' command, continuing execution
195/// until the specified frame ID returns.
196void Debugger::finishProgram(void *Frame) {
197 assert(isProgramRunning() && "Cannot cont if the program isn't running!");
198 try {
199 Process->finishProgram(Frame);
200 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000201 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000202 throw NonErrorException("The program stopped with exit code " +
203 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000204 } catch (...) {
205 killProgram();
206 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000207 }
208}
209
210/// contProgram - Implement the 'cont' command, continuing execution until
211/// the next breakpoint is encountered.
212void Debugger::contProgram() {
213 assert(isProgramRunning() && "Cannot cont if the program isn't running!");
214 try {
215 Process->contProgram();
216 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000217 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000218 throw NonErrorException("The program stopped with exit code " +
219 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000220 } catch (...) {
221 killProgram();
222 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000223 }
224}