| OLD | NEW |
| 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
| 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ | 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
| 3 /* This Source Code Form is subject to the terms of the Mozilla Public | 3 /* This Source Code Form is subject to the terms of the Mozilla Public |
| 4 * License, v. 2.0. If a copy of the MPL was not distributed with this | 4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 6 | 6 |
| 7 #include "ThreadStackHelper.h" | 7 #include "ThreadStackHelper.h" |
| 8 #include "MainThreadUtils.h" | 8 #include "MainThreadUtils.h" |
| 9 #include "nsJSPrincipals.h" | 9 #include "nsJSPrincipals.h" |
| 10 #include "nsScriptSecurityManager.h" | 10 #include "nsScriptSecurityManager.h" |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 #ifdef MOZ_THREADSTACKHELPER_NATIVE | 410 #ifdef MOZ_THREADSTACKHELPER_NATIVE |
| 411 ThreadContext context; | 411 ThreadContext context; |
| 412 context.mStack = MakeUnique<uint8_t[]>(ThreadContext::kMaxStackSize); | 412 context.mStack = MakeUnique<uint8_t[]>(ThreadContext::kMaxStackSize); |
| 413 | 413 |
| 414 ScopedSetPtr<ThreadContext> contextPtr(mContextToFill, &context); | 414 ScopedSetPtr<ThreadContext> contextPtr(mContextToFill, &context); |
| 415 | 415 |
| 416 // Get pseudostack first and fill the thread context. | 416 // Get pseudostack first and fill the thread context. |
| 417 GetStack(aStack); | 417 GetStack(aStack); |
| 418 NS_ENSURE_TRUE_VOID(context.mValid); | 418 NS_ENSURE_TRUE_VOID(context.mValid); |
| 419 | 419 |
| 420 CodeModulesProvider modulesProvider; | |
| 421 google_breakpad::BasicCodeModules modules(&modulesProvider); | |
| 422 google_breakpad::BasicSourceLineResolver resolver; | |
| 423 google_breakpad::StackFrameSymbolizer symbolizer(nullptr, &resolver); | |
| 424 | |
| 425 #if defined(MOZ_THREADSTACKHELPER_X86) | |
| 426 google_breakpad::StackwalkerX86 stackWalker( | |
| 427 nullptr, &context.mContext, &context, &modules, &symbolizer); | |
| 428 #elif defined(MOZ_THREADSTACKHELPER_X64) | |
| 429 google_breakpad::StackwalkerAMD64 stackWalker( | |
| 430 nullptr, &context.mContext, &context, &modules, &symbolizer); | |
| 431 #elif defined(MOZ_THREADSTACKHELPER_ARM) | |
| 432 google_breakpad::StackwalkerARM stackWalker( | |
| 433 nullptr, &context.mContext, -1, &context, &modules, &symbolizer); | |
| 434 #else | |
| 435 #error "Unsupported architecture" | |
| 436 #endif | |
| 437 | |
| 438 google_breakpad::CallStack callStack; | |
| 439 std::vector<const google_breakpad::CodeModule*> modules_without_symbols; | |
| 440 | |
| 441 google_breakpad::Stackwalker::set_max_frames(ThreadContext::kMaxStackFrames); | |
| 442 google_breakpad::Stackwalker:: | |
| 443 set_max_frames_scanned(ThreadContext::kMaxStackFrames); | |
| 444 | |
| 445 NS_ENSURE_TRUE_VOID(stackWalker.Walk(&callStack, &modules_without_symbols)); | |
| 446 | |
| 447 const std::vector<google_breakpad::StackFrame*>& frames(*callStack.frames()); | |
| 448 for (intptr_t i = frames.size() - 1; i >= 0; i--) { | |
| 449 const google_breakpad::StackFrame& frame = *frames[i]; | |
| 450 if (!frame.module) { | |
| 451 continue; | |
| 452 } | |
| 453 const string& module = frame.module->code_file(); | |
| 454 #if defined(XP_LINUX) || defined(XP_MACOSX) | |
| 455 const char PATH_SEP = '/'; | |
| 456 #elif defined(XP_WIN) | |
| 457 const char PATH_SEP = '\\'; | |
| 458 #endif | |
| 459 const char* const module_basename = strrchr(module.c_str(), PATH_SEP); | |
| 460 const char* const module_name = module_basename ? | |
| 461 module_basename + 1 : module.c_str(); | |
| 462 | |
| 463 char buffer[0x100]; | |
| 464 size_t len = 0; | |
| 465 if (!frame.function_name.empty()) { | |
| 466 len = PR_snprintf(buffer, sizeof(buffer), "%s:%s", | |
| 467 module_name, frame.function_name.c_str()); | |
| 468 } else { | |
| 469 len = PR_snprintf(buffer, sizeof(buffer), "%s:0x%p", | |
| 470 module_name, (intptr_t) | |
| 471 (frame.instruction - frame.module->base_address())); | |
| 472 } | |
| 473 if (len) { | |
| 474 aStack.AppendViaBuffer(buffer, len); | |
| 475 } | |
| 476 } | |
| 477 #endif // MOZ_THREADSTACKHELPER_NATIVE | 420 #endif // MOZ_THREADSTACKHELPER_NATIVE |
| 478 } | 421 } |
| 479 | 422 |
| 480 #ifdef XP_LINUX | 423 #ifdef XP_LINUX |
| 481 | 424 |
| 482 int ThreadStackHelper::sInitialized; | 425 int ThreadStackHelper::sInitialized; |
| 483 int ThreadStackHelper::sFillStackSignum; | 426 int ThreadStackHelper::sFillStackSignum; |
| 484 | 427 |
| 485 void | 428 void |
| 486 ThreadStackHelper::FillStackHandler(int aSignal, siginfo_t* aInfo, | 429 ThreadStackHelper::FillStackHandler(int aSignal, siginfo_t* aInfo, |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 } | 798 } |
| 856 #endif | 799 #endif |
| 857 | 800 |
| 858 mContextToFill->mStackBase = uintptr_t(sp); | 801 mContextToFill->mStackBase = uintptr_t(sp); |
| 859 mContextToFill->mStackSize = stackSize; | 802 mContextToFill->mStackSize = stackSize; |
| 860 mContextToFill->mValid = true; | 803 mContextToFill->mValid = true; |
| 861 #endif // MOZ_THREADSTACKHELPER_NATIVE | 804 #endif // MOZ_THREADSTACKHELPER_NATIVE |
| 862 } | 805 } |
| 863 | 806 |
| 864 } // namespace mozilla | 807 } // namespace mozilla |
| OLD | NEW |