| 143 | } |
| 144 | |
| 145 | Result Debugger::start(const char** argv, const char** envp, |
| 146 | const boost::filesystem::path& workingDirectory) { |
| 147 | assert(boost::filesystem::is_directory(workingDirectory)); |
| 148 | |
| 149 | Result res; |
| 150 | |
| 151 | if (!mTarget.IsValid()) { |
| 152 | res.addEntry("EUKN", "Cannot start a debugger process with an invalid target", {}); |
| 153 | return res; |
| 154 | } |
| 155 | |
| 156 | // generate IR |
| 157 | std::unique_ptr<llvm::Module> mod; |
| 158 | { |
| 159 | res = module().context().compileModule(module(), true, &mod); |
| 160 | if (!res) { return res; } |
| 161 | } |
| 162 | |
| 163 | // write it to a file |
| 164 | fs::path tmpIRPath; |
| 165 | { |
| 166 | tmpIRPath = boost::filesystem::temp_directory_path() / fs::unique_path(); |
| 167 | std::error_code ec; // TODO: use ec |
| 168 | std::string errorString; // only for LLVM 3.5 |
| 169 | llvm::raw_fd_ostream file { |
| 170 | tmpIRPath.string().c_str(), |
| 171 | #if LLVM_VERSION_LESS_EQUAL(3, 5) |
| 172 | errorString, |
| 173 | #else |
| 174 | ec, |
| 175 | #endif |
| 176 | llvm::sys::fs::F_RW |
| 177 | }; |
| 178 | llvm::WriteBitcodeToFile(mod.get(), file); |
| 179 | } |
| 180 | |
| 181 | // create args |
| 182 | std::vector<const char*> args; |
| 183 | { |
| 184 | args.push_back("interpret"); |
| 185 | args.push_back("-i"); |
| 186 | args.push_back(tmpIRPath.string().c_str()); |
| 187 | args.push_back("-O"); |
| 188 | args.push_back("0"); |
| 189 | |
| 190 | if (argv != nullptr) { |
| 191 | for (; *argv != nullptr; ++argv) { args.push_back(*argv); } |
| 192 | } |
| 193 | |
| 194 | args.push_back(nullptr); |
| 195 | } |
| 196 | |
| 197 | // start the process |
| 198 | { |
| 199 | lldb::SBError err; |
| 200 | lldb::SBListener invalidListener; |
| 201 | mProcess = |
| 202 | mTarget.Launch(invalidListener, args.data(), envp, nullptr, nullptr, nullptr, |