waterbox: When compiled in debug mode, forcibly evict self at every opportunity. This can be used to catch bugs using pointers past their valid time. Catch and fix two such bugs in the libsnes wrapper.
This commit is contained in:
parent
91e239e11f
commit
fa9dcfae35
|
@ -458,6 +458,14 @@ namespace BizHawk.Common
|
|||
{
|
||||
DeleteFileW(path + ":Zone.Identifier");
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern bool IsDebuggerPresent();
|
||||
|
||||
public static bool IsDebuggerReallyPresent()
|
||||
{
|
||||
return IsDebuggerPresent();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -62,9 +62,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
|||
PlainHeapSizeKB = 2 * 1024, // TODO: wasn't there more in here?
|
||||
SealedHeapSizeKB = 128 * 1024
|
||||
});
|
||||
|
||||
_core = BizInvoker.GetInvoker<CoreImpl>(_exe, _exe);
|
||||
_comm = (CommStruct*)_core.DllInit().ToPointer();
|
||||
using (_exe.EnterExit())
|
||||
{
|
||||
_core = BizInvoker.GetInvoker<CoreImpl>(_exe, _exe);
|
||||
_comm = (CommStruct*)_core.DllInit().ToPointer();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||
{
|
||||
|
@ -13,40 +14,46 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
|||
|
||||
public byte[] CloneSaveRam()
|
||||
{
|
||||
byte* buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM);
|
||||
var size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM);
|
||||
if (buf == null)
|
||||
using (Api.EnterExit())
|
||||
{
|
||||
buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.SGB_CARTRAM);
|
||||
size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.SGB_CARTRAM);
|
||||
}
|
||||
byte* buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM);
|
||||
var size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM);
|
||||
if (buf == null)
|
||||
{
|
||||
buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.SGB_CARTRAM);
|
||||
size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.SGB_CARTRAM);
|
||||
}
|
||||
|
||||
var ret = new byte[size];
|
||||
Marshal.Copy((IntPtr)buf, ret, 0, size);
|
||||
return ret;
|
||||
var ret = new byte[size];
|
||||
Marshal.Copy((IntPtr)buf, ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public void StoreSaveRam(byte[] data)
|
||||
{
|
||||
byte* buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM);
|
||||
var size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM);
|
||||
if (buf == null)
|
||||
using (Api.EnterExit())
|
||||
{
|
||||
buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.SGB_CARTRAM);
|
||||
size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.SGB_CARTRAM);
|
||||
}
|
||||
byte* buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM);
|
||||
var size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.CARTRIDGE_RAM);
|
||||
if (buf == null)
|
||||
{
|
||||
buf = Api.QUERY_get_memory_data(LibsnesApi.SNES_MEMORY.SGB_CARTRAM);
|
||||
size = Api.QUERY_get_memory_size(LibsnesApi.SNES_MEMORY.SGB_CARTRAM);
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (size != data.Length)
|
||||
{
|
||||
throw new InvalidOperationException("Somehow, we got a mismatch between saveram size and what bsnes says the saveram size is");
|
||||
}
|
||||
if (size != data.Length)
|
||||
{
|
||||
throw new InvalidOperationException("Somehow, we got a mismatch between saveram size and what bsnes says the saveram size is");
|
||||
}
|
||||
|
||||
Marshal.Copy(data, 0, (IntPtr)buf, size);
|
||||
Marshal.Copy(data, 0, (IntPtr)buf, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -734,8 +734,10 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
_syscalls.Init();
|
||||
|
||||
Console.WriteLine("About to enter unmanaged code");
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
if (Win32Hacks.IsDebuggerReallyPresent() && !System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
// this means that GDB or another unconventional debugger is attached.
|
||||
// if that's the case, and it's observing this core, it probably wants a break
|
||||
System.Diagnostics.Debugger.Break();
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,12 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
{
|
||||
public object Sync;
|
||||
private WeakReference LoadedRef = new WeakReference(null);
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// recursive lock count
|
||||
/// </summary>
|
||||
public int LockCount;
|
||||
#endif
|
||||
public Swappable Loaded
|
||||
{
|
||||
get
|
||||
|
@ -78,6 +84,10 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
public void Enter()
|
||||
{
|
||||
Monitor.Enter(_currentLockInfo.Sync);
|
||||
#if DEBUG
|
||||
if (_currentLockInfo.LockCount++ != 0 && _currentLockInfo.Loaded != this)
|
||||
throw new InvalidOperationException("Woops!");
|
||||
#endif
|
||||
if (_currentLockInfo.Loaded != this)
|
||||
{
|
||||
if (_currentLockInfo.Loaded != null)
|
||||
|
@ -93,6 +103,16 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
/// </summary>
|
||||
public void Exit()
|
||||
{
|
||||
#if DEBUG
|
||||
// when debugging, if we're releasing the lock then deactivate
|
||||
if (_currentLockInfo.LockCount-- == 1)
|
||||
{
|
||||
if (_currentLockInfo.Loaded != this)
|
||||
throw new InvalidOperationException("Woops!");
|
||||
DeactivateInternal();
|
||||
_currentLockInfo.Loaded = null;
|
||||
}
|
||||
#endif
|
||||
Monitor.Exit(_currentLockInfo.Sync);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue