On Thursday, December 1, 2022 at 2:55:32 PM UTC,
[email protected] wrote:
How do I debug an ExternalCallback that crashes the image?
Using the VisualStudio debugger open on the dolphin project attached to the Dolphin process. However, if you are not familiar with debugging at an assembler level, you may find the learning curve steep. Generally it is not necessary anyway. I'd start by
googling the Win32 error code "gobbledygook" in the errors file to understand the class of problem (stack fault or other access violation), and then carefully check my callback descriptor against the API documentation and (if necessary and available) the
source. I'd probably only crack open the VS debugger for this in the absence of complete documentation and/or source.
The callback is defined as:
ExternalCallback
block: [ :time :event :sequencer :data | Transcript display: time; cr. nil ] descriptor: (ExternalDescriptor
callingConvention: 'stdcall:'
returnType: 'void'
argumentTypes: 'word FluidEvent* FluidSequencer* lpvoid').
Based on this definition (from https://www.fluidsynth.org/api/group__sequencer.html#gae6bb99d73ba67f0b7e15883b78bfae85):
typedef void(* fluid_event_callback_t) (unsigned int time, fluid_event_t *event, fluid_sequencer_t *seq, void *data)
I can see that the callback descriptor is incorrect - the first argument is an unsigned int, so would be 32-bits not 16, i.e. `dword` not `word`. This would cause you other problems than the crash you describe, however.
Every time the callback gets invoked, the body gets executed and then the image crashes. I suspect it has to do with the return type, but I've tried returning nil, 0, 1, true, false, and self all to no avail.
Returning the wrong type of object from the block will not cause the behaviour you see. In this case the return value will be totally ignored because the callback has no return value (it is `void`). If it did have a return value, then returning a type of
object that cannot be coerced to the return type might result in Dolphin reporting an error, or it might cause a subsequent access violation if the return type is a pointer and you return nil/zero or the address of some object that goes out of scope and
gets GC'd. None of that can possibly apply here.
DPRO.ERRORS just has some gobbledygook about an unhandled Win32 exception, ...
Which you are choosing to disparage because you don't understand it? It is likely that the details require to diagnose the fault are in that gobbledygook. I'd imagine the exception code is one of the stack fault codes.
and if I put a halt statement in the callback, the crash seems to somewhere around a call to ProcessScheduler>>callback:return:, which again points to an issue with the return type.
No, it doesn't. It suggests you have got the calling convention wrong. To be sure you'd have to examine the original source and build definition (if not documented), but the chances are that it is using the default C calling convention, so cdecl, not
stdcall. Using the wrong one of these would certainly result in a crash on return, because these employ different conventions at to whether caller or callee is responsible for adjusting the stack pointer.
From searching this group, the problem seems to recur over and over again and there don't seem to be any general solutions.
The general solution is to take care to define the callback correctly. You are describing a machine level interaction, so there is almost no margin for error. If you are familiar with development at assembly level, then this requires the same level of
precision. Many developers do not have a grounding in assembler these days (it is rather old hat), hence it is not uncommon to run into problems with describing callbacks correctly. If you do not use the correct calling convention, or you get the
arguments or return type wrong, then the machine stack will likely be corrupted and the process will crash very directly. If you get an immediate crash, often without seeing the Windows crash report dialog, then you can safely assume you have corrupted
the stack due to defining the callback incorrectly.
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)