| 243 | |
| 244 | |
| 245 | bool LldbAdapter::Attach(std::uint32_t pid) |
| 246 | { |
| 247 | m_debugger.SetAsync(true); |
| 248 | |
| 249 | std::thread thread([&]() { EventListener(); }); |
| 250 | thread.detach(); |
| 251 | |
| 252 | SBError err; |
| 253 | |
| 254 | // *Attempt* to create a functional target triple for the binary. |
| 255 | // This allows attaching to fat binaries. If the triple is empty, it will still attach on thin binaries. |
| 256 | auto archName = lldbArchNameForBinaryNinjaArchName(m_defaultArchitecture); |
| 257 | std::string triple = ""; |
| 258 | if (!archName.empty()) |
| 259 | triple = archName + "-unknown-none"; |
| 260 | |
| 261 | m_target = m_debugger.CreateTarget(m_originalFileName.c_str(), triple.c_str(), "", true, err); |
| 262 | |
| 263 | if (!m_target.IsValid()) |
| 264 | { |
| 265 | // It is likely lldb did not like our target triple. |
| 266 | if (err.GetCString() && std::string(err.GetCString()).find("is not compatible with") != std::string::npos) |
| 267 | { |
| 268 | // Last-ditch effort. If it is a thin binary, we will be able to attach without passing a triple. |
| 269 | m_target = m_debugger.CreateTarget(m_originalFileName.c_str(), "", "", true, err); |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | if (!m_target.IsValid()) |
| 274 | { |
| 275 | DebuggerEvent event; |
| 276 | event.type = LaunchFailureEventType; |
| 277 | event.data.errorData.shortError = fmt::format("LLDB failed to attach to target."); |
| 278 | event.data.errorData.error = |
| 279 | fmt::format("LLDB failed to attach to target with \"{}\"", err.GetCString() ? err.GetCString() : ""); |
| 280 | PostDebuggerEvent(event); |
| 281 | return false; |
| 282 | } |
| 283 | |
| 284 | m_targetActive = true; |
| 285 | ApplyBreakpoints(); |
| 286 | |
| 287 | SBAttachInfo info(pid); |
| 288 | m_process = m_target.Attach(info, err); |
| 289 | if (!m_process.IsValid() || (m_process.GetState() == StateType::eStateInvalid) || err.Fail()) |
| 290 | { |
| 291 | DebuggerEvent event; |
| 292 | event.type = LaunchFailureEventType; |
| 293 | event.data.errorData.shortError = fmt::format("LLDB failed to attach to target."); |
| 294 | event.data.errorData.error = |
| 295 | fmt::format("LLDB Failed to attach to target with \"{}\"", err.GetCString() ? err.GetCString() : ""); |
| 296 | PostDebuggerEvent(event); |
| 297 | return false; |
| 298 | } |
| 299 | |
| 300 | // LLDB event listener does not get an event when the attach operation completes, so we must send an event here. |
| 301 | // This is NOT needed for Connect(), since LLDB event listener sends an event in that case. |
| 302 | DebuggerEvent dbgevt; |
nothing calls this directly
no test coverage detected