Reverting back to original 1.8 version so I can manually merge in patch.
[llvm-complete.git] / lib / Debugger / Debugger.cpp
bloba0505bda578a69d0ba2ad9f3e0c1014767a17e92
1 //===-- Debugger.cpp - LLVM debugger library implementation ---------------===//
2 //
3 // 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.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the main implementation of the LLVM debugger library.
12 //===----------------------------------------------------------------------===//
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"
19 #include "llvm/ADT/StringExtras.h"
20 #include <memory>
21 using namespace llvm;
23 /// Debugger constructor - Initialize the debugger to its initial, empty, state.
24 ///
25 Debugger::Debugger() : Environment(0), Program(0), Process(0) {
28 Debugger::~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 &) {
37 unloadProgram();
40 /// getProgramPath - Get the path of the currently loaded program, or an
41 /// empty string if none is loaded.
42 std::string Debugger::getProgramPath() const {
43 return Program ? Program->getModuleIdentifier() : "";
46 static Module *
47 getMaterializedModuleProvider(const std::string &Filename) {
48 try {
49 std::auto_ptr<ModuleProvider> Result(getBytecodeModuleProvider(Filename));
50 if (!Result.get()) return 0;
52 Result->materializeModule();
53 return Result.release()->releaseModule();
54 } catch (...) {
55 return 0;
59 /// loadProgram - If a program is currently loaded, unload it. Then search
60 /// the PATH for the specified program, loading it when found. If the
61 /// specified program cannot be found, an exception is thrown to indicate the
62 /// error.
63 void Debugger::loadProgram(const std::string &Filename) {
64 if ((Program = getMaterializedModuleProvider(Filename)) ||
65 (Program = getMaterializedModuleProvider(Filename+".bc")))
66 return; // Successfully loaded the program.
68 // Search the program path for the file...
69 if (const char *PathS = getenv("PATH")) {
70 std::string Path = PathS;
72 std::string Directory = getToken(Path, ":");
73 while (!Directory.empty()) {
74 if ((Program = getMaterializedModuleProvider(Directory +"/"+ Filename)) ||
75 (Program = getMaterializedModuleProvider(Directory +"/"+ Filename
76 + ".bc")))
77 return; // Successfully loaded the program.
79 Directory = getToken(Path, ":");
83 throw "Could not find program '" + Filename + "'!";
86 /// unloadProgram - If a program is running, kill it, then unload all traces
87 /// of the current program. If no program is loaded, this method silently
88 /// succeeds.
89 void Debugger::unloadProgram() {
90 if (!isProgramLoaded()) return;
91 killProgram();
92 delete Program;
93 Program = 0;
97 /// createProgram - Create an instance of the currently loaded program,
98 /// killing off any existing one. This creates the program and stops it at
99 /// the first possible moment. If there is no program loaded or if there is a
100 /// problem starting the program, this method throws an exception.
101 void Debugger::createProgram() {
102 if (!isProgramLoaded())
103 throw "Cannot start program: none is loaded.";
105 // Kill any existing program.
106 killProgram();
108 // Add argv[0] to the arguments vector..
109 std::vector<std::string> Args(ProgramArguments);
110 Args.insert(Args.begin(), getProgramPath());
112 // Start the new program... this could throw if the program cannot be started.
113 Process = InferiorProcess::create(Program, Args, Environment);
116 InferiorProcess *
117 InferiorProcess::create(Module *M, const std::vector<std::string> &Arguments,
118 const char * const *envp) {
119 throw"No supported binding to inferior processes (debugger not implemented).";
122 /// killProgram - If the program is currently executing, kill off the
123 /// process and free up any state related to the currently running program. If
124 /// there is no program currently running, this just silently succeeds.
125 void Debugger::killProgram() {
126 // The destructor takes care of the dirty work.
127 try {
128 delete Process;
129 } catch (...) {
130 Process = 0;
131 throw;
133 Process = 0;
136 /// stepProgram - Implement the 'step' command, continuing execution until
137 /// the next possible stop point.
138 void Debugger::stepProgram() {
139 assert(isProgramRunning() && "Cannot step if the program isn't running!");
140 try {
141 Process->stepProgram();
142 } catch (InferiorProcessDead &IPD) {
143 killProgram();
144 throw NonErrorException("The program stopped with exit code " +
145 itostr(IPD.getExitCode()));
146 } catch (...) {
147 killProgram();
148 throw;
152 /// nextProgram - Implement the 'next' command, continuing execution until
153 /// the next possible stop point that is in the current function.
154 void Debugger::nextProgram() {
155 assert(isProgramRunning() && "Cannot next if the program isn't running!");
156 try {
157 // This should step the process. If the process enters a function, then it
158 // should 'finish' it. However, figuring this out is tricky. In
159 // particular, the program can do any of:
160 // 0. Not change current frame.
161 // 1. Entering or exiting a region within the current function
162 // (which changes the frame ID, but which we shouldn't 'finish')
163 // 2. Exiting the current function (which changes the frame ID)
164 // 3. Entering a function (which should be 'finish'ed)
165 // For this reason, we have to be very careful about when we decide to do
166 // the 'finish'.
168 // Get the current frame, but don't trust it. It could change...
169 void *CurrentFrame = Process->getPreviousFrame(0);
171 // Don't trust the current frame: get the caller frame.
172 void *ParentFrame = Process->getPreviousFrame(CurrentFrame);
174 // Ok, we have some information, run the program one step.
175 Process->stepProgram();
177 // Where is the new frame? The most common case, by far is that it has not
178 // been modified (Case #0), in which case we don't need to do anything more.
179 void *NewFrame = Process->getPreviousFrame(0);
180 if (NewFrame != CurrentFrame) {
181 // Ok, the frame changed. If we are case #1, then the parent frame will
182 // be identical.
183 void *NewParentFrame = Process->getPreviousFrame(NewFrame);
184 if (ParentFrame != NewParentFrame) {
185 // Ok, now we know we aren't case #0 or #1. Check to see if we entered
186 // a new function. If so, the parent frame will be "CurrentFrame".
187 if (CurrentFrame == NewParentFrame)
188 Process->finishProgram(NewFrame);
192 } catch (InferiorProcessDead &IPD) {
193 killProgram();
194 throw NonErrorException("The program stopped with exit code " +
195 itostr(IPD.getExitCode()));
196 } catch (...) {
197 killProgram();
198 throw;
202 /// finishProgram - Implement the 'finish' command, continuing execution
203 /// until the specified frame ID returns.
204 void Debugger::finishProgram(void *Frame) {
205 assert(isProgramRunning() && "Cannot cont if the program isn't running!");
206 try {
207 Process->finishProgram(Frame);
208 } catch (InferiorProcessDead &IPD) {
209 killProgram();
210 throw NonErrorException("The program stopped with exit code " +
211 itostr(IPD.getExitCode()));
212 } catch (...) {
213 killProgram();
214 throw;
218 /// contProgram - Implement the 'cont' command, continuing execution until
219 /// the next breakpoint is encountered.
220 void Debugger::contProgram() {
221 assert(isProgramRunning() && "Cannot cont if the program isn't running!");
222 try {
223 Process->contProgram();
224 } catch (InferiorProcessDead &IPD) {
225 killProgram();
226 throw NonErrorException("The program stopped with exit code " +
227 itostr(IPD.getExitCode()));
228 } catch (...) {
229 killProgram();
230 throw;