1 //===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Target/ThreadPlanCallFunction.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 #include "llvm/Support/MachO.h" 16 // Project includes 17 #include "lldb/lldb-private-log.h" 18 #include "lldb/Breakpoint/Breakpoint.h" 19 #include "lldb/Breakpoint/BreakpointLocation.h" 20 #include "lldb/Core/Address.h" 21 #include "lldb/Core/Log.h" 22 #include "lldb/Core/Stream.h" 23 #include "lldb/Target/LanguageRuntime.h" 24 #include "lldb/Target/Process.h" 25 #include "lldb/Target/RegisterContext.h" 26 #include "lldb/Target/StopInfo.h" 27 #include "lldb/Target/Target.h" 28 #include "lldb/Target/Thread.h" 29 #include "lldb/Target/ThreadPlanRunToAddress.h" 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 //---------------------------------------------------------------------- 35 // ThreadPlanCallFunction: Plan to call a single function 36 //---------------------------------------------------------------------- 37 38 ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, 39 Address &function, 40 addr_t arg, 41 bool stop_other_threads, 42 bool discard_on_error, 43 addr_t *this_arg, 44 addr_t *cmd_arg) : 45 ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), 46 m_valid (false), 47 m_stop_other_threads (stop_other_threads), 48 m_function_addr (function), 49 m_function_sp (NULL), 50 m_takedown_done (false), 51 m_stop_address (LLDB_INVALID_ADDRESS) 52 { 53 SetOkayToDiscard (discard_on_error); 54 55 Process& process = thread.GetProcess(); 56 Target& target = process.GetTarget(); 57 const ABI *abi = process.GetABI().get(); 58 59 if (!abi) 60 return; 61 62 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 63 64 SetBreakpoints(); 65 66 m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 67 68 Module *exe_module = target.GetExecutableModulePointer(); 69 70 if (exe_module == NULL) 71 { 72 if (log) 73 log->Printf ("Can't execute code without an executable module."); 74 return; 75 } 76 else 77 { 78 ObjectFile *objectFile = exe_module->GetObjectFile(); 79 if (!objectFile) 80 { 81 if (log) 82 log->Printf ("Could not find object file for module \"%s\".", 83 exe_module->GetFileSpec().GetFilename().AsCString()); 84 return; 85 } 86 m_start_addr = objectFile->GetEntryPointAddress(); 87 if (!m_start_addr.IsValid()) 88 { 89 if (log) 90 log->Printf ("Could not find entry point address for executable module \"%s\".", 91 exe_module->GetFileSpec().GetFilename().AsCString()); 92 return; 93 } 94 } 95 96 addr_t start_load_addr = m_start_addr.GetLoadAddress(&target); 97 98 // Checkpoint the thread state so we can restore it later. 99 if (log && log->GetVerbose()) 100 ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); 101 102 if (!thread.CheckpointThreadState (m_stored_thread_state)) 103 { 104 if (log) 105 log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); 106 return; 107 } 108 // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... 109 thread.SetStopInfoToNothing(); 110 111 addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target); 112 113 if (this_arg && cmd_arg) 114 { 115 if (!abi->PrepareTrivialCall (thread, 116 m_function_sp, 117 FunctionLoadAddr, 118 start_load_addr, 119 this_arg, 120 cmd_arg, 121 &arg)) 122 return; 123 } 124 else if (this_arg) 125 { 126 if (!abi->PrepareTrivialCall (thread, 127 m_function_sp, 128 FunctionLoadAddr, 129 start_load_addr, 130 this_arg, 131 &arg)) 132 return; 133 } 134 else 135 { 136 if (!abi->PrepareTrivialCall (thread, 137 m_function_sp, 138 FunctionLoadAddr, 139 start_load_addr, 140 &arg)) 141 return; 142 } 143 144 ReportRegisterState ("Function call was set up. Register state was:"); 145 146 m_valid = true; 147 } 148 149 150 ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread, 151 Address &function, 152 bool stop_other_threads, 153 bool discard_on_error, 154 addr_t *arg1_ptr, 155 addr_t *arg2_ptr, 156 addr_t *arg3_ptr, 157 addr_t *arg4_ptr, 158 addr_t *arg5_ptr, 159 addr_t *arg6_ptr) : 160 ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion), 161 m_valid (false), 162 m_stop_other_threads (stop_other_threads), 163 m_function_addr (function), 164 m_function_sp(NULL), 165 m_takedown_done (false) 166 { 167 SetOkayToDiscard (discard_on_error); 168 169 Process& process = thread.GetProcess(); 170 Target& target = process.GetTarget(); 171 const ABI *abi = process.GetABI().get(); 172 173 if (!abi) 174 return; 175 176 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 177 178 SetBreakpoints(); 179 180 m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize(); 181 182 Module *exe_module = target.GetExecutableModulePointer(); 183 184 if (exe_module == NULL) 185 { 186 if (log) 187 log->Printf ("Can't execute code without an executable module."); 188 return; 189 } 190 else 191 { 192 ObjectFile *objectFile = exe_module->GetObjectFile(); 193 if (!objectFile) 194 { 195 if (log) 196 log->Printf ("Could not find object file for module \"%s\".", 197 exe_module->GetFileSpec().GetFilename().AsCString()); 198 return; 199 } 200 m_start_addr = objectFile->GetEntryPointAddress(); 201 if (!m_start_addr.IsValid()) 202 { 203 if (log) 204 log->Printf ("Could not find entry point address for executable module \"%s\".", 205 exe_module->GetFileSpec().GetFilename().AsCString()); 206 return; 207 } 208 } 209 210 addr_t start_load_addr = m_start_addr.GetLoadAddress(&target); 211 212 // Checkpoint the thread state so we can restore it later. 213 if (log && log->GetVerbose()) 214 ReportRegisterState ("About to checkpoint thread before function call. Original register state was:"); 215 216 if (!thread.CheckpointThreadState (m_stored_thread_state)) 217 { 218 if (log) 219 log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state."); 220 return; 221 } 222 // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding... 223 thread.SetStopInfoToNothing(); 224 225 addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(&target); 226 227 if (!abi->PrepareTrivialCall (thread, 228 m_function_sp, 229 FunctionLoadAddr, 230 start_load_addr, 231 arg1_ptr, 232 arg2_ptr, 233 arg3_ptr, 234 arg4_ptr, 235 arg5_ptr, 236 arg6_ptr)) 237 { 238 return; 239 } 240 241 ReportRegisterState ("Function call was set up. Register state was:"); 242 243 m_valid = true; 244 } 245 246 ThreadPlanCallFunction::~ThreadPlanCallFunction () 247 { 248 } 249 250 void 251 ThreadPlanCallFunction::ReportRegisterState (const char *message) 252 { 253 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE)); 254 if (log) 255 { 256 StreamString strm; 257 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); 258 259 log->PutCString(message); 260 261 RegisterValue reg_value; 262 263 for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount(); 264 reg_idx < num_registers; 265 ++reg_idx) 266 { 267 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); 268 if (reg_ctx->ReadRegister(reg_info, reg_value)) 269 { 270 reg_value.Dump(&strm, reg_info, true, false, eFormatDefault); 271 strm.EOL(); 272 } 273 } 274 log->PutCString(strm.GetData()); 275 } 276 } 277 278 void 279 ThreadPlanCallFunction::DoTakedown () 280 { 281 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 282 if (!m_takedown_done) 283 { 284 // TODO: how do we tell if all went well? 285 if (m_return_value_sp) 286 { 287 const ABI *abi = m_thread.GetProcess().GetABI().get(); 288 if (abi) 289 abi->GetReturnValue(m_thread, *m_return_value_sp); 290 } 291 if (log) 292 log->Printf ("DoTakedown called for thread 0x%4.4llx, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete()); 293 m_takedown_done = true; 294 m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC(); 295 m_real_stop_info_sp = GetPrivateStopReason(); 296 m_thread.RestoreThreadStateFromCheckpoint(m_stored_thread_state); 297 SetPlanComplete(); 298 ClearBreakpoints(); 299 if (log && log->GetVerbose()) 300 ReportRegisterState ("Restoring thread state after function call. Restored register state:"); 301 302 } 303 else 304 { 305 if (log) 306 log->Printf ("DoTakedown called as no-op for thread 0x%4.4llx, m_valid: %d complete: %d.\n", m_thread.GetID(), m_valid, IsPlanComplete()); 307 } 308 } 309 310 void 311 ThreadPlanCallFunction::WillPop () 312 { 313 DoTakedown(); 314 } 315 316 void 317 ThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level) 318 { 319 if (level == eDescriptionLevelBrief) 320 { 321 s->Printf("Function call thread plan"); 322 } 323 else 324 { 325 s->Printf("Thread plan to call 0x%llx", m_function_addr.GetLoadAddress(&m_thread.GetProcess().GetTarget())); 326 } 327 } 328 329 bool 330 ThreadPlanCallFunction::ValidatePlan (Stream *error) 331 { 332 if (!m_valid) 333 return false; 334 335 return true; 336 } 337 338 bool 339 ThreadPlanCallFunction::PlanExplainsStop () 340 { 341 m_real_stop_info_sp = GetPrivateStopReason(); 342 343 // If our subplan knows why we stopped, even if it's done (which would forward the question to us) 344 // we answer yes. 345 if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop()) 346 return true; 347 348 // Check if the breakpoint is one of ours. 349 350 if (BreakpointsExplainStop()) 351 return true; 352 353 // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack. 354 if (!OkayToDiscard()) 355 return false; 356 357 // Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on. 358 // If it is not an internal breakpoint, consult OkayToDiscard. 359 360 if (m_real_stop_info_sp && m_real_stop_info_sp->GetStopReason() == eStopReasonBreakpoint) 361 { 362 uint64_t break_site_id = m_real_stop_info_sp->GetValue(); 363 BreakpointSiteSP bp_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID(break_site_id); 364 if (bp_site_sp) 365 { 366 uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); 367 bool is_internal = true; 368 for (uint32_t i = 0; i < num_owners; i++) 369 { 370 Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); 371 372 if (!bp.IsInternal()) 373 { 374 is_internal = false; 375 break; 376 } 377 } 378 if (is_internal) 379 return false; 380 } 381 382 return OkayToDiscard(); 383 } 384 else 385 { 386 // If the subplan is running, any crashes are attributable to us. 387 // If we want to discard the plan, then we say we explain the stop 388 // but if we are going to be discarded, let whoever is above us 389 // explain the stop. 390 return ((m_subplan_sp.get() != NULL) && !OkayToDiscard()); 391 } 392 } 393 394 bool 395 ThreadPlanCallFunction::ShouldStop (Event *event_ptr) 396 { 397 if (PlanExplainsStop()) 398 { 399 ReportRegisterState ("Function completed. Register state was:"); 400 401 DoTakedown(); 402 403 return true; 404 } 405 else 406 { 407 return false; 408 } 409 } 410 411 bool 412 ThreadPlanCallFunction::StopOthers () 413 { 414 return m_stop_other_threads; 415 } 416 417 void 418 ThreadPlanCallFunction::SetStopOthers (bool new_value) 419 { 420 if (m_subplan_sp) 421 { 422 ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get()); 423 address_plan->SetStopOthers(new_value); 424 } 425 m_stop_other_threads = new_value; 426 } 427 428 StateType 429 ThreadPlanCallFunction::GetPlanRunState () 430 { 431 return eStateRunning; 432 } 433 434 void 435 ThreadPlanCallFunction::DidPush () 436 { 437 //#define SINGLE_STEP_EXPRESSIONS 438 439 #ifndef SINGLE_STEP_EXPRESSIONS 440 m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads)); 441 442 m_thread.QueueThreadPlan(m_subplan_sp, false); 443 m_subplan_sp->SetPrivate (true); 444 #endif 445 } 446 447 bool 448 ThreadPlanCallFunction::WillStop () 449 { 450 return true; 451 } 452 453 bool 454 ThreadPlanCallFunction::MischiefManaged () 455 { 456 if (IsPlanComplete()) 457 { 458 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 459 460 if (log) 461 log->Printf("Completed call function plan."); 462 463 ThreadPlan::MischiefManaged (); 464 return true; 465 } 466 else 467 { 468 return false; 469 } 470 } 471 472 void 473 ThreadPlanCallFunction::SetBreakpoints () 474 { 475 m_cxx_language_runtime = m_thread.GetProcess().GetLanguageRuntime(eLanguageTypeC_plus_plus); 476 m_objc_language_runtime = m_thread.GetProcess().GetLanguageRuntime(eLanguageTypeObjC); 477 478 if (m_cxx_language_runtime) 479 m_cxx_language_runtime->SetExceptionBreakpoints(); 480 if (m_objc_language_runtime) 481 m_objc_language_runtime->SetExceptionBreakpoints(); 482 } 483 484 void 485 ThreadPlanCallFunction::ClearBreakpoints () 486 { 487 if (m_cxx_language_runtime) 488 m_cxx_language_runtime->ClearExceptionBreakpoints(); 489 if (m_objc_language_runtime) 490 m_objc_language_runtime->ClearExceptionBreakpoints(); 491 } 492 493 bool 494 ThreadPlanCallFunction::BreakpointsExplainStop() 495 { 496 StopInfoSP stop_info_sp = GetPrivateStopReason(); 497 498 if (m_cxx_language_runtime && 499 m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) 500 return true; 501 502 if (m_objc_language_runtime && 503 m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)) 504 return true; 505 506 return false; 507 } 508