DEBUGGING WASM GAUGES
It's inevitable that while you build and test your WASM module, you will encounter bugs that you will need to fix. However, before you can begin that process, you should have installed the WASM Debug Extension for Visual Studio, as that resolves certain issues that VS has when dealing with web assembly. You can find more information here:
Additionally, within the simulation you may open a debug window that can help with resolving issues. This can be found from the DevMode Debug Menu:
Debug Guidelines
The list below outlines the basic steps that you need to follow to correctly debug a WASM module using Visual Studio:
- Open your project in Visual Studio.
- Build it and copy the WebAssembly module to the panel folder of your SimObject.
- Launch Microsoft Flight Simulator 2024.
- When the game is running, use the Debug > Attach to process command of Visual Studio.
- In the processes list, select
Microsoft Flight Simulator.exe
and press theAttach
button. - Once in the main menu, open your project.
- Build the package.
- Launch a flight with your SimObject.
- Once the game has loaded your SimObject, the breakpoints set in the project become active and you can step into your code.
Edit And Continue
It is possible to recompile some parts of your project while it is executing (and it will keep the same memory). To be able to do this, you must use Edit And Continue compatible WASM in Debug mode. In this case "compatible" means the most up-to-date version supplied with the most recent SDK release.
The general workflow for Edit And Continue is as follows:
- Make some changes to your C++ code.
- Open the WASM Debug Window and select your package.
- Click on the "Experimental" node with the Recompile button and press it.
- Your new code will be compiled, and the WASM will be patched. Note that some logs and popups will tell you exactly what has happened (ie: success, failure, descriptions...).
Keep in mind that there are some limitations:
- You can't update an existing type.
- You can't add a new member to a class, for example, but you can add functions/methods.
- If you want to make a lot of changes, it is safer to make a clean new WASM.
Known Issues And Limitations When Debugging
The following are a list of potential known issues and limitations that you may come across when debugging your modules:
- The Watch windows work with global variables and memory address. For local variables, use the Locals and Autos windows.
- Stepping into a function may display the Disassembly window instead of the original C/C++ source code.
- If you have any function in the WASM module that does not call another function (ie: it's the last function call in the stack), this function needs to have the macro
WASM_FORCE_DEBUG
within it, otherwise any debug output for the function will, essentially, be garbage. The image below shows an example of this:
only required if you are not using the VS Wasm Debugger Extension.void EventHandler(ID32 event, UINT32 evdata, PVOID userdata ) { WASM_FORCE_DEBUG; bool bNotCallingAnyFunctionHere = true; }
- When a WASM module is being compiled by MSFS, the following error can appear in the console:
WASM: ERR_VALIDATION_ERROR (-4095 / fffff001)
It usually means that a function declared as "imported" in the WASM module is not found when linking the compiled module with the MSFS libraries. So, keep in mind that:- When compiling C/C++ to WASM through the MSFS Platform Toolset in Visual Studio, functions that are declared but not implemented in the C/C++ code are automatically flagged as "imported".
- When MSFS recompiles the WASM module it must resolve all these "imported" functions (i.e. find them in the MSFS libraries)
-
wasm_call_ctors
is the function called to construct the globals of the WASM module. If you get a crash using this function then you should be able to compile the module with debuggging, and in DevMode use the "Wasm Debug Mode" optiopn. This should allow you to determine what is going wrong.
-
If you get the
0xC0000005
Access Violation, then your code trying to access an invalid memory location. The two main reasons that can lead to this are as follows:-
You have tried read/write to an invalid address due to an error with the pointer arithmetic, an uninitialized value, an out of bound array, or using a previously freed pointer.
-
The stack is full and a read/write has occured giving a stack overflow error.
To determine the problem, the first step is to look at the callstack. If there is a function at the top
_innative_internal_env_chkstk
then this is a stack overflow (and not a smallone - the function used at least 65536 bytes - so consider moving some data onto the heap). The next step is simply to watch which pointer is reading/writing and then determine if this is a variable on the stack or allocated on the heap, something like this:void main() { int varOnStack[42]; int* varOnHeap = (int*)malloc(42 * sizeof(int)); }
-