0
0
Fork 0
mirror of https://github.com/ryujinx-mirror/ryujinx.git synced 2024-12-23 02:45:45 +00:00

Print stack trace on invalid memory accesses (#461)

* Print stack trace on invalid memory accesses

* Rebased, change code region base address for 39-bits address space, print stack trace on break and undefined instructions too
This commit is contained in:
gdkchan 2018-10-20 19:07:52 -03:00 committed by Ac_K
parent 0e1e094b7a
commit 2cb8541462
5 changed files with 53 additions and 1 deletions

View file

@ -0,0 +1,14 @@
using System;
namespace ChocolArm64.Events
{
public class AInvalidAccessEventArgs : EventArgs
{
public long Position { get; private set; }
public AInvalidAccessEventArgs(long Position)
{
this.Position = Position;
}
}
}

View file

@ -1,3 +1,4 @@
using ChocolArm64.Events;
using ChocolArm64.Exceptions; using ChocolArm64.Exceptions;
using ChocolArm64.State; using ChocolArm64.State;
using System; using System;
@ -51,6 +52,8 @@ namespace ChocolArm64.Memory
private byte*** PageTable; private byte*** PageTable;
public event EventHandler<AInvalidAccessEventArgs> InvalidAccess;
public AMemory(IntPtr Ram) public AMemory(IntPtr Ram)
{ {
Monitors = new Dictionary<int, ArmMonitor>(); Monitors = new Dictionary<int, ArmMonitor>();
@ -512,6 +515,8 @@ Unmapped:
return (byte*)Ptr + (Position & PageMask); return (byte*)Ptr + (Position & PageMask);
} }
InvalidAccess?.Invoke(this, new AInvalidAccessEventArgs(Position));
throw new VmmPageFaultException(Position); throw new VmmPageFaultException(Position);
} }
@ -560,6 +565,8 @@ Unmapped:
return (byte*)Ptr + (Position & PageMask); return (byte*)Ptr + (Position & PageMask);
} }
InvalidAccess?.Invoke(this, new AInvalidAccessEventArgs(Position));
throw new VmmPageFaultException(Position); throw new VmmPageFaultException(Position);
} }

View file

@ -91,7 +91,7 @@ namespace Ryujinx.HLE.HOS.Kernel
break; break;
case AddressSpaceType.Addr39Bits: case AddressSpaceType.Addr39Bits:
CodeRegionStart = 0; CodeRegionStart = 0x8000000;
CodeRegionSize = 0x80000000; CodeRegionSize = 0x80000000;
MapRegionSize = 0x1000000000; MapRegionSize = 0x1000000000;
HeapRegionSize = 0x180000000; HeapRegionSize = 0x180000000;

View file

@ -67,6 +67,8 @@ namespace Ryujinx.HLE.HOS
Memory = new AMemory(Device.Memory.RamPointer); Memory = new AMemory(Device.Memory.RamPointer);
Memory.InvalidAccess += CpuInvalidAccessHandler;
MemoryManager = new KMemoryManager(this); MemoryManager = new KMemoryManager(this);
TlsPages = new List<KTlsPageManager>(); TlsPages = new List<KTlsPageManager>();
@ -283,11 +285,15 @@ namespace Ryujinx.HLE.HOS
private void BreakHandler(object sender, AInstExceptionEventArgs e) private void BreakHandler(object sender, AInstExceptionEventArgs e)
{ {
PrintStackTraceForCurrentThread();
throw new GuestBrokeExecutionException(); throw new GuestBrokeExecutionException();
} }
private void UndefinedHandler(object sender, AInstUndefinedEventArgs e) private void UndefinedHandler(object sender, AInstUndefinedEventArgs e)
{ {
PrintStackTraceForCurrentThread();
throw new UndefinedInstructionException(e.Position, e.RawOpCode); throw new UndefinedInstructionException(e.Position, e.RawOpCode);
} }
@ -334,6 +340,24 @@ namespace Ryujinx.HLE.HOS
return Translator; return Translator;
} }
private void CpuInvalidAccessHandler(object sender, AInvalidAccessEventArgs e)
{
PrintStackTraceForCurrentThread();
}
private void PrintStackTraceForCurrentThread()
{
foreach (KThread Thread in Threads.Values)
{
if (Thread.Context.IsCurrentThread())
{
PrintStackTrace(Thread.Context.ThreadState);
break;
}
}
}
public void PrintStackTrace(AThreadState ThreadState) public void PrintStackTrace(AThreadState ThreadState)
{ {
StringBuilder Trace = new StringBuilder(); StringBuilder Trace = new StringBuilder();

View file

@ -125,6 +125,13 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
//As of now, it assumes that HostChannelsCount == 2. //As of now, it assumes that HostChannelsCount == 2.
WaveBuffer Wb = WaveBuffers[BufferIndex]; WaveBuffer Wb = WaveBuffers[BufferIndex];
if (Wb.Position == 0)
{
Samples = new int[0];
return;
}
if (SampleFormat == SampleFormat.PcmInt16) if (SampleFormat == SampleFormat.PcmInt16)
{ {
int SamplesCount = (int)(Wb.Size / (sizeof(short) * ChannelsCount)); int SamplesCount = (int)(Wb.Size / (sizeof(short) * ChannelsCount));