diff --git a/BizHawk.Common/Win32Hacks.cs b/BizHawk.Common/Win32Hacks.cs index 7126f0e7b2..9770518d38 100644 --- a/BizHawk.Common/Win32Hacks.cs +++ b/BizHawk.Common/Win32Hacks.cs @@ -458,6 +458,14 @@ namespace BizHawk.Common { DeleteFileW(path + ":Zone.Identifier"); } + + [DllImport("kernel32.dll")] + static extern bool IsDebuggerPresent(); + + public static bool IsDebuggerReallyPresent() + { + return IsDebuggerPresent(); + } } } \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs index 62ae3c73a7..545db1b271 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesApi.cs @@ -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(_exe, _exe); - _comm = (CommStruct*)_core.DllInit().ToPointer(); + using (_exe.EnterExit()) + { + _core = BizInvoker.GetInvoker(_exe, _exe); + _comm = (CommStruct*)_core.DllInit().ToPointer(); + } } public void Dispose() diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISaveRam.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISaveRam.cs index 0cf3e94476..67753f69d5 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISaveRam.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.ISaveRam.cs @@ -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); + } } } } diff --git a/BizHawk.Emulation.Cores/Waterbox/PeRunner.cs b/BizHawk.Emulation.Cores/Waterbox/PeRunner.cs index 8852d3588d..85a59ba762 100644 --- a/BizHawk.Emulation.Cores/Waterbox/PeRunner.cs +++ b/BizHawk.Emulation.Cores/Waterbox/PeRunner.cs @@ -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(); } diff --git a/BizHawk.Emulation.Cores/Waterbox/Swappable.cs b/BizHawk.Emulation.Cores/Waterbox/Swappable.cs index 25d3d8d0e9..2eff85f9a7 100644 --- a/BizHawk.Emulation.Cores/Waterbox/Swappable.cs +++ b/BizHawk.Emulation.Cores/Waterbox/Swappable.cs @@ -54,6 +54,12 @@ namespace BizHawk.Emulation.Cores.Waterbox { public object Sync; private WeakReference LoadedRef = new WeakReference(null); +#if DEBUG + /// + /// recursive lock count + /// + 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 /// 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); }