blob: 90741afc8e012115f2030b7fc6b3c609d94c53c2 [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"
Chris Lattner2cb1ad92007-05-06 05:18:53 +000018#include "llvm/Bitcode/ReaderWriter.h"
Chris Lattner2eacf262004-01-05 05:25:10 +000019#include "llvm/Debugger/InferiorProcess.h"
Chris Lattner2cb1ad92007-05-06 05:18:53 +000020#include "llvm/Support/MemoryBuffer.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000021#include "llvm/ADT/StringExtras.h"
Duraid Madina4547e222005-12-26 10:24:15 +000022#include <memory>
Chris Lattner2eacf262004-01-05 05:25:10 +000023using namespace llvm;
24
Chris Lattner2cb1ad92007-05-06 05:18:53 +000025static bool Bitcode = false;
26
Chris Lattner2eacf262004-01-05 05:25:10 +000027/// Debugger constructor - Initialize the debugger to its initial, empty, state.
28///
29Debugger::Debugger() : Environment(0), Program(0), Process(0) {
30}
31
32Debugger::~Debugger() {
33 // Killing the program could throw an exception. We don't want to progagate
34 // the exception out of our destructor though.
35 try {
36 killProgram();
37 } catch (const char *) {
38 } catch (const std::string &) {
39 }
Misha Brukmanedf128a2005-04-21 22:36:52 +000040
Chris Lattner2eacf262004-01-05 05:25:10 +000041 unloadProgram();
42}
43
44/// getProgramPath - Get the path of the currently loaded program, or an
45/// empty string if none is loaded.
46std::string Debugger::getProgramPath() const {
47 return Program ? Program->getModuleIdentifier() : "";
48}
49
50static Module *
51getMaterializedModuleProvider(const std::string &Filename) {
Chris Lattner2cb1ad92007-05-06 05:18:53 +000052 if (Bitcode) {
53 return ParseBytecodeFile(Filename);
54 } else {
55 std::auto_ptr<MemoryBuffer> Buffer;
56 Buffer.reset(MemoryBuffer::getFileOrSTDIN(&Filename[0], Filename.size()));
57 if (Buffer.get())
58 return ParseBitcodeFile(Buffer.get());
59 return 0;
60 }
Chris Lattner2eacf262004-01-05 05:25:10 +000061}
62
63/// loadProgram - If a program is currently loaded, unload it. Then search
64/// the PATH for the specified program, loading it when found. If the
65/// specified program cannot be found, an exception is thrown to indicate the
66/// error.
67void Debugger::loadProgram(const std::string &Filename) {
68 if ((Program = getMaterializedModuleProvider(Filename)) ||
69 (Program = getMaterializedModuleProvider(Filename+".bc")))
70 return; // Successfully loaded the program.
71
72 // Search the program path for the file...
73 if (const char *PathS = getenv("PATH")) {
74 std::string Path = PathS;
75
76 std::string Directory = getToken(Path, ":");
77 while (!Directory.empty()) {
78 if ((Program = getMaterializedModuleProvider(Directory +"/"+ Filename)) ||
79 (Program = getMaterializedModuleProvider(Directory +"/"+ Filename
80 + ".bc")))
81 return; // Successfully loaded the program.
82
83 Directory = getToken(Path, ":");
84 }
85 }
86
87 throw "Could not find program '" + Filename + "'!";
88}
89
90/// unloadProgram - If a program is running, kill it, then unload all traces
91/// of the current program. If no program is loaded, this method silently
92/// succeeds.
93void Debugger::unloadProgram() {
94 if (!isProgramLoaded()) return;
95 killProgram();
96 delete Program;
97 Program = 0;
98}
99
100
101/// createProgram - Create an instance of the currently loaded program,
102/// killing off any existing one. This creates the program and stops it at
103/// the first possible moment. If there is no program loaded or if there is a
104/// problem starting the program, this method throws an exception.
105void Debugger::createProgram() {
106 if (!isProgramLoaded())
107 throw "Cannot start program: none is loaded.";
108
109 // Kill any existing program.
110 killProgram();
111
112 // Add argv[0] to the arguments vector..
113 std::vector<std::string> Args(ProgramArguments);
114 Args.insert(Args.begin(), getProgramPath());
115
116 // Start the new program... this could throw if the program cannot be started.
117 Process = InferiorProcess::create(Program, Args, Environment);
118}
119
Chris Lattner89b19262006-03-10 22:39:48 +0000120InferiorProcess *
121InferiorProcess::create(Module *M, const std::vector<std::string> &Arguments,
122 const char * const *envp) {
123 throw"No supported binding to inferior processes (debugger not implemented).";
124}
125
Chris Lattner2eacf262004-01-05 05:25:10 +0000126/// killProgram - If the program is currently executing, kill off the
127/// process and free up any state related to the currently running program. If
128/// there is no program currently running, this just silently succeeds.
129void Debugger::killProgram() {
130 // The destructor takes care of the dirty work.
Chris Lattnerde31b762004-01-14 20:58:17 +0000131 try {
132 delete Process;
133 } catch (...) {
134 Process = 0;
135 throw;
136 }
Chris Lattner2eacf262004-01-05 05:25:10 +0000137 Process = 0;
138}
139
140/// stepProgram - Implement the 'step' command, continuing execution until
141/// the next possible stop point.
142void Debugger::stepProgram() {
143 assert(isProgramRunning() && "Cannot step if the program isn't running!");
144 try {
145 Process->stepProgram();
146 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000147 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000148 throw NonErrorException("The program stopped with exit code " +
149 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000150 } catch (...) {
151 killProgram();
152 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000153 }
154}
155
156/// nextProgram - Implement the 'next' command, continuing execution until
157/// the next possible stop point that is in the current function.
158void Debugger::nextProgram() {
159 assert(isProgramRunning() && "Cannot next if the program isn't running!");
160 try {
161 // This should step the process. If the process enters a function, then it
162 // should 'finish' it. However, figuring this out is tricky. In
163 // particular, the program can do any of:
164 // 0. Not change current frame.
165 // 1. Entering or exiting a region within the current function
166 // (which changes the frame ID, but which we shouldn't 'finish')
167 // 2. Exiting the current function (which changes the frame ID)
168 // 3. Entering a function (which should be 'finish'ed)
169 // For this reason, we have to be very careful about when we decide to do
170 // the 'finish'.
171
172 // Get the current frame, but don't trust it. It could change...
173 void *CurrentFrame = Process->getPreviousFrame(0);
174
175 // Don't trust the current frame: get the caller frame.
176 void *ParentFrame = Process->getPreviousFrame(CurrentFrame);
Misha Brukmanedf128a2005-04-21 22:36:52 +0000177
Chris Lattner2eacf262004-01-05 05:25:10 +0000178 // Ok, we have some information, run the program one step.
179 Process->stepProgram();
180
181 // Where is the new frame? The most common case, by far is that it has not
182 // been modified (Case #0), in which case we don't need to do anything more.
183 void *NewFrame = Process->getPreviousFrame(0);
184 if (NewFrame != CurrentFrame) {
185 // Ok, the frame changed. If we are case #1, then the parent frame will
186 // be identical.
187 void *NewParentFrame = Process->getPreviousFrame(NewFrame);
188 if (ParentFrame != NewParentFrame) {
189 // Ok, now we know we aren't case #0 or #1. Check to see if we entered
190 // a new function. If so, the parent frame will be "CurrentFrame".
191 if (CurrentFrame == NewParentFrame)
192 Process->finishProgram(NewFrame);
193 }
194 }
195
196 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000197 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000198 throw NonErrorException("The program stopped with exit code " +
199 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000200 } catch (...) {
201 killProgram();
202 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000203 }
204}
205
206/// finishProgram - Implement the 'finish' command, continuing execution
207/// until the specified frame ID returns.
208void Debugger::finishProgram(void *Frame) {
209 assert(isProgramRunning() && "Cannot cont if the program isn't running!");
210 try {
211 Process->finishProgram(Frame);
212 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000213 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000214 throw NonErrorException("The program stopped with exit code " +
215 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000216 } catch (...) {
217 killProgram();
218 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000219 }
220}
221
222/// contProgram - Implement the 'cont' command, continuing execution until
223/// the next breakpoint is encountered.
224void Debugger::contProgram() {
225 assert(isProgramRunning() && "Cannot cont if the program isn't running!");
226 try {
227 Process->contProgram();
228 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000229 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000230 throw NonErrorException("The program stopped with exit code " +
231 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000232 } catch (...) {
233 killProgram();
234 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000235 }
236}