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