Browse Source
Merge pull request #1847 from ogniK5377/backtrace-break
Print backtrace on svcBreak
pull/15/merge
bunnei
7 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with
41 additions and
1 deletions
-
src/core/CMakeLists.txt
-
src/core/arm/arm_interface.cpp
-
src/core/arm/arm_interface.h
-
src/core/arm/unicorn/arm_unicorn.cpp
-
src/core/hle/kernel/svc.cpp
-
src/core/hle/service/fatal/fatal.cpp
|
|
|
@ -1,5 +1,6 @@ |
|
|
|
add_library(core STATIC |
|
|
|
arm/arm_interface.h |
|
|
|
arm/arm_interface.cpp |
|
|
|
arm/exclusive_monitor.cpp |
|
|
|
arm/exclusive_monitor.h |
|
|
|
arm/unicorn/arm_unicorn.cpp |
|
|
|
|
|
|
|
@ -0,0 +1,26 @@ |
|
|
|
// Copyright 2018 yuzu emulator team
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#include "arm_interface.h"
|
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "common/logging/log.h"
|
|
|
|
#include "core/memory.h"
|
|
|
|
|
|
|
|
namespace Core { |
|
|
|
void ARM_Interface::LogBacktrace() { |
|
|
|
VAddr fp = GetReg(29); |
|
|
|
VAddr lr = GetReg(30); |
|
|
|
VAddr sp = GetReg(13); |
|
|
|
VAddr pc = GetPC(); |
|
|
|
LOG_ERROR(Core_ARM, "Backtrace, sp={:016X}, pc={:016X}", sp, pc); |
|
|
|
for (;;) { |
|
|
|
LOG_ERROR(Core_ARM, "{:016X}", lr); |
|
|
|
if (!fp) { |
|
|
|
break; |
|
|
|
} |
|
|
|
lr = Memory::Read64(fp + 8) - 4; |
|
|
|
fp = Memory::Read64(fp); |
|
|
|
} |
|
|
|
} |
|
|
|
}; // namespace Core
|
|
|
|
@ -141,6 +141,14 @@ public: |
|
|
|
|
|
|
|
/// Prepare core for thread reschedule (if needed to correctly handle state) |
|
|
|
virtual void PrepareReschedule() = 0; |
|
|
|
|
|
|
|
/// fp (= r29) points to the last frame record. |
|
|
|
/// Note that this is the frame record for the *previous* frame, not the current one. |
|
|
|
/// Note we need to subtract 4 from our last read to get the proper address |
|
|
|
/// Frame records are two words long: |
|
|
|
/// fp+0 : pointer to previous frame record |
|
|
|
/// fp+8 : value of lr for frame |
|
|
|
void LogBacktrace(); |
|
|
|
}; |
|
|
|
|
|
|
|
} // namespace Core |
|
|
|
@ -10,6 +10,7 @@ |
|
|
|
#include "core/core.h"
|
|
|
|
#include "core/core_timing.h"
|
|
|
|
#include "core/hle/kernel/svc.h"
|
|
|
|
#include "core/memory.h"
|
|
|
|
|
|
|
|
namespace Core { |
|
|
|
|
|
|
|
|
|
|
|
@ -684,6 +684,9 @@ static void Break(u32 reason, u64 info1, u64 info2) { |
|
|
|
"Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}", |
|
|
|
reason, info1, info2); |
|
|
|
handle_debug_buffer(info1, info2); |
|
|
|
Core::System::GetInstance() |
|
|
|
.ArmInterface(static_cast<std::size_t>(GetCurrentThread()->GetProcessorID())) |
|
|
|
.LogBacktrace(); |
|
|
|
ASSERT(false); |
|
|
|
|
|
|
|
Core::CurrentProcess()->PrepareForTermination(); |
|
|
|
|
|
|
|
@ -111,7 +111,8 @@ static void GenerateErrorReport(ResultCode error_code, const FatalInfo& info) { |
|
|
|
} |
|
|
|
|
|
|
|
static void ThrowFatalError(ResultCode error_code, FatalType fatal_type, const FatalInfo& info) { |
|
|
|
LOG_ERROR(Service_Fatal, "Threw fatal error type {}", static_cast<u32>(fatal_type)); |
|
|
|
LOG_ERROR(Service_Fatal, "Threw fatal error type {} with error code 0x{:X}", |
|
|
|
static_cast<u32>(fatal_type), error_code.raw); |
|
|
|
switch (fatal_type) { |
|
|
|
case FatalType::ErrorReportAndScreen: |
|
|
|
GenerateErrorReport(error_code, info); |
|
|
|
|