blob: 77fd2ac96bea03ecaced4f74cebedccca08da951 [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//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// 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"
Chris Lattner2cb1ad92007-05-06 05:18:53 +000017#include "llvm/Bitcode/ReaderWriter.h"
Chris Lattner2eacf262004-01-05 05:25:10 +000018#include "llvm/Debugger/InferiorProcess.h"
Chris Lattner2cb1ad92007-05-06 05:18:53 +000019#include "llvm/Support/MemoryBuffer.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000020#include "llvm/ADT/StringExtras.h"
Dan Gohmand68a0762009-01-05 17:59:02 +000021#include <cstdlib>
Duraid Madina4547e222005-12-26 10:24:15 +000022#include <memory>
Chris Lattner2eacf262004-01-05 05:25:10 +000023using namespace llvm;
24
25/// Debugger constructor - Initialize the debugger to its initial, empty, state.
26///
27Debugger::Debugger() : Environment(0), Program(0), Process(0) {
28}
29
30Debugger::~Debugger() {
31 // Killing the program could throw an exception. We don't want to progagate
32 // the exception out of our destructor though.
33 try {
34 killProgram();
35 } catch (const char *) {
36 } catch (const std::string &) {
37 }
Misha Brukmanedf128a2005-04-21 22:36:52 +000038
Chris Lattner2eacf262004-01-05 05:25:10 +000039 unloadProgram();
40}
41
42/// getProgramPath - Get the path of the currently loaded program, or an
43/// empty string if none is loaded.
44std::string Debugger::getProgramPath() const {
45 return Program ? Program->getModuleIdentifier() : "";
46}
47
48static Module *
Owen Anderson31895e72009-07-01 21:22:36 +000049getMaterializedModuleProvider(const std::string &Filename,
Owen Anderson4434ed42009-07-01 23:13:44 +000050 LLVMContext& C) {
Chris Lattner4bcca0f2007-05-06 09:29:13 +000051 std::auto_ptr<MemoryBuffer> Buffer;
Chris Lattner038112a2008-04-01 18:04:03 +000052 Buffer.reset(MemoryBuffer::getFileOrSTDIN(Filename.c_str()));
Chris Lattner4bcca0f2007-05-06 09:29:13 +000053 if (Buffer.get())
Owen Anderson8b477ed2009-07-01 16:58:40 +000054 return ParseBitcodeFile(Buffer.get(), C);
Chris Lattner4bcca0f2007-05-06 09:29:13 +000055 return 0;
Chris Lattner2eacf262004-01-05 05:25:10 +000056}
57
58/// loadProgram - If a program is currently loaded, unload it. Then search
59/// the PATH for the specified program, loading it when found. If the
60/// specified program cannot be found, an exception is thrown to indicate the
61/// error.
Owen Anderson4434ed42009-07-01 23:13:44 +000062void Debugger::loadProgram(const std::string &Filename, LLVMContext& C) {
Owen Anderson8b477ed2009-07-01 16:58:40 +000063 if ((Program = getMaterializedModuleProvider(Filename, C)) ||
64 (Program = getMaterializedModuleProvider(Filename+".bc", C)))
Chris Lattner2eacf262004-01-05 05:25:10 +000065 return; // Successfully loaded the program.
66
67 // Search the program path for the file...
68 if (const char *PathS = getenv("PATH")) {
69 std::string Path = PathS;
70
71 std::string Directory = getToken(Path, ":");
72 while (!Directory.empty()) {
Owen Anderson8b477ed2009-07-01 16:58:40 +000073 if ((Program = getMaterializedModuleProvider(Directory +"/"+ Filename, C))
74 || (Program = getMaterializedModuleProvider(Directory +"/"+ Filename
75 + ".bc", C)))
Chris Lattner2eacf262004-01-05 05:25:10 +000076 return; // Successfully loaded the program.
77
78 Directory = getToken(Path, ":");
79 }
80 }
81
82 throw "Could not find program '" + Filename + "'!";
83}
84
85/// unloadProgram - If a program is running, kill it, then unload all traces
86/// of the current program. If no program is loaded, this method silently
87/// succeeds.
88void Debugger::unloadProgram() {
89 if (!isProgramLoaded()) return;
90 killProgram();
91 delete Program;
92 Program = 0;
93}
94
95
96/// createProgram - Create an instance of the currently loaded program,
97/// killing off any existing one. This creates the program and stops it at
98/// the first possible moment. If there is no program loaded or if there is a
99/// problem starting the program, this method throws an exception.
100void Debugger::createProgram() {
101 if (!isProgramLoaded())
102 throw "Cannot start program: none is loaded.";
103
104 // Kill any existing program.
105 killProgram();
106
107 // Add argv[0] to the arguments vector..
108 std::vector<std::string> Args(ProgramArguments);
109 Args.insert(Args.begin(), getProgramPath());
110
111 // Start the new program... this could throw if the program cannot be started.
112 Process = InferiorProcess::create(Program, Args, Environment);
113}
114
Chris Lattner89b19262006-03-10 22:39:48 +0000115InferiorProcess *
116InferiorProcess::create(Module *M, const std::vector<std::string> &Arguments,
117 const char * const *envp) {
118 throw"No supported binding to inferior processes (debugger not implemented).";
119}
120
Chris Lattner2eacf262004-01-05 05:25:10 +0000121/// killProgram - If the program is currently executing, kill off the
122/// process and free up any state related to the currently running program. If
123/// there is no program currently running, this just silently succeeds.
124void Debugger::killProgram() {
125 // The destructor takes care of the dirty work.
Chris Lattnerde31b762004-01-14 20:58:17 +0000126 try {
127 delete Process;
128 } catch (...) {
129 Process = 0;
130 throw;
131 }
Chris Lattner2eacf262004-01-05 05:25:10 +0000132 Process = 0;
133}
134
135/// stepProgram - Implement the 'step' command, continuing execution until
136/// the next possible stop point.
137void Debugger::stepProgram() {
138 assert(isProgramRunning() && "Cannot step if the program isn't running!");
139 try {
140 Process->stepProgram();
141 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000142 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000143 throw NonErrorException("The program stopped with exit code " +
144 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000145 } catch (...) {
146 killProgram();
147 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000148 }
149}
150
151/// nextProgram - Implement the 'next' command, continuing execution until
152/// the next possible stop point that is in the current function.
153void Debugger::nextProgram() {
154 assert(isProgramRunning() && "Cannot next if the program isn't running!");
155 try {
156 // This should step the process. If the process enters a function, then it
157 // should 'finish' it. However, figuring this out is tricky. In
158 // particular, the program can do any of:
159 // 0. Not change current frame.
160 // 1. Entering or exiting a region within the current function
161 // (which changes the frame ID, but which we shouldn't 'finish')
162 // 2. Exiting the current function (which changes the frame ID)
163 // 3. Entering a function (which should be 'finish'ed)
164 // For this reason, we have to be very careful about when we decide to do
165 // the 'finish'.
166
167 // Get the current frame, but don't trust it. It could change...
168 void *CurrentFrame = Process->getPreviousFrame(0);
169
170 // Don't trust the current frame: get the caller frame.
171 void *ParentFrame = Process->getPreviousFrame(CurrentFrame);
Misha Brukmanedf128a2005-04-21 22:36:52 +0000172
Chris Lattner2eacf262004-01-05 05:25:10 +0000173 // Ok, we have some information, run the program one step.
174 Process->stepProgram();
175
176 // Where is the new frame? The most common case, by far is that it has not
177 // been modified (Case #0), in which case we don't need to do anything more.
178 void *NewFrame = Process->getPreviousFrame(0);
179 if (NewFrame != CurrentFrame) {
180 // Ok, the frame changed. If we are case #1, then the parent frame will
181 // be identical.
182 void *NewParentFrame = Process->getPreviousFrame(NewFrame);
183 if (ParentFrame != NewParentFrame) {
184 // Ok, now we know we aren't case #0 or #1. Check to see if we entered
185 // a new function. If so, the parent frame will be "CurrentFrame".
186 if (CurrentFrame == NewParentFrame)
187 Process->finishProgram(NewFrame);
188 }
189 }
190
191 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000192 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000193 throw NonErrorException("The program stopped with exit code " +
194 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000195 } catch (...) {
196 killProgram();
197 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000198 }
199}
200
201/// finishProgram - Implement the 'finish' command, continuing execution
202/// until the specified frame ID returns.
203void Debugger::finishProgram(void *Frame) {
204 assert(isProgramRunning() && "Cannot cont if the program isn't running!");
205 try {
206 Process->finishProgram(Frame);
207 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000208 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000209 throw NonErrorException("The program stopped with exit code " +
210 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000211 } catch (...) {
212 killProgram();
213 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000214 }
215}
216
217/// contProgram - Implement the 'cont' command, continuing execution until
218/// the next breakpoint is encountered.
219void Debugger::contProgram() {
220 assert(isProgramRunning() && "Cannot cont if the program isn't running!");
221 try {
222 Process->contProgram();
223 } catch (InferiorProcessDead &IPD) {
Chris Lattnerde31b762004-01-14 20:58:17 +0000224 killProgram();
Chris Lattner2eacf262004-01-05 05:25:10 +0000225 throw NonErrorException("The program stopped with exit code " +
226 itostr(IPD.getExitCode()));
Chris Lattnerde31b762004-01-14 20:58:17 +0000227 } catch (...) {
228 killProgram();
229 throw;
Chris Lattner2eacf262004-01-05 05:25:10 +0000230 }
231}