WASM DEBUG
The WASM Debug window is activated from the Debug menu and can be used get information about the different WASM modules that are currently loaded. When you first open the window you will be presented with the WASM Section tab showing the currently registered WebAssembly modules, and the other tabs will be greyed out. To commence debugging and get access to the other tabs you will need to select the module that should be debugged by choosing one from the Modules drop-down list at the top of the window. Once one has been selected, the window will update to show additional information, as explained in the sections below.
WASM Section
On this tab you can find the following information:
- Number of registered modules: the number of different modules loaded, ie: the number of
*.wasm
. - Standalones: the total number of Standalone WebAssembly modules currently running
- Airports: the total number of WASM airports running.
- Gauges: the total number of WASM gauges running.
- Systems: the total number of WASM systems running.
Note that one module may run several airports or several gauges and systems.
There is also the tick box Time waiting draw. Since WebAssembly modules are run in parallel with the main thread of the simulation, to draw anything the main thread needs to wait until the end of the draw callbacks. This checkbox will expand to show a graph that illustrates this time spent waiting:
If this time is high (relative to the duration of a frame - 16ms) and the game lags, then this is probably caused by a WebAssembly module.
Module Section
The Module Section tab gives you information on the module currently selected:
Here you can see the Status of the module, which will be listed with one of the following messages:
- UNKNOWN: This should never appear and if it does then it means there is an unknown error with the module.
- COMPILING: The WASM file is being converted to a DLL.
- INITIALISING: The DLL has been created and it is being loaded.
- READY: The WASM module is loaded and ready to be used.
- FAILED: The compilation of the WASM to a DLL failed (you can look at the console to get more information).
- DIRTY: The WASM module was ready but an error occurred in the user's code (you can check the console to get more information). In this state, the WASM module won't be used.
After that you have the Is Encrypted status, which will be either true or false. If it's true, then there will be less information shown, as the encryption process makes certain things irrelevant. Below this - if the module isn't encrypted - you can see the Dll Path and then WASM Build Type and the DLL Build Type.
NOTE: If the DLL Build Type is set to Debug, it's because you have enabled WASM Debug Mode.
These should be the same and ideally be Release for a production package (mismatching build types will be flagged with an error message, as shown in the image below).
Recompile
After the Build Type, you may have a Recompile
button and a log window. This is available when the the build types (WASM and DLL) are both set to DEBUG (see here for information: Debugging WebAssembly Modules), and lets you use the Edit and Continue capabilities, as you can edit the code then click the Recompile
button and see the results.
When recompiling you will be shown some logs and popups that will tell you exactly what has happened, including whether the recompilation has been a success or a a failure, some descriptions of any issues, etc...
Using this feature, please keep in mind that:
- You can't update an existing type.
- You can't add a new member to a class, for example, but you can add new functions/methods.
- If you want to make a lot of changes, it is safer to make a clean new WASM module.
Module Information
After the recompilation section there is the section showing various pieces of information about the module and its performance. Here you have the following fields:
- Module task status: This gives you the status of the task linked to the module being inspected. It will be one of the following:
- Module task is not started - The module task has never started,. This may be caused by an error during compilation.
- Module task is running - The module task is running.
- Module task has been stopped (Done) - The task has been stopped. This may be caused by the module being unloaded or recompiled.
- Module Step: This tells you what the module is currently doing when the debug window performs it's draw tick, not what the module has done during the frame. It can be one of the following:
- Unknown - The module has not been started
- Idle - Module is not currently computing: This is the most common state, and it does not mean that the module has done nothing during the frame, only that computation is finished (update/draw/one time) so the step is idle.
- Updating - Module is computing its updates
- Drawing - Module is computing its draws
- Calling callbacks - Module is computing callbacks
- Paused - Module is currently paused to do long computation: Some API calls may be done over several frames, so the module is paused because of that.
- Stopped- Module has been stopped
- Unknown: You should never get a simple "Unknown" message. If this happens then please report it as a bug on DevSupport.
Finally you have the following two fields:
- Is Module Stop Required: The simulation has requested the module to stop (recompilation, dirty, etc…)
- Is Module To Be Removed: The simulation has requested the removal of this module (dirty, etc…)
Performance
The performance section has an All Updates checkbox, and may also have additional checkboxes depending on the contents of the module. These checkboxs show the times that updates, draws, and callbacks take for the selected module (as text), and if you click the checkbox then a performance graph will be shown.
Under this section you have the following field:
- No data written at address 0: In WebAssembly, address 0 is a valid address which means a pointer value can be 0 and can be de-referenced without crashing (for example, in C++, if you de-reference a
nulltpr
it will crash). So even if this is valid, it shouldn’t be made. Having any data at address 0 indicates an “error” in your code.
Purpose Section
The Purpose Section tab meant for you to debug what the selected module is doing:
On this tab you will need to select the module to get information about, and then after that you will have the following fields filled out (note that not all fields will be visible, as it will depend on the module which ones are relevant):
- Status: The selected module status, which can be one of the following:
- UNKNOWN: This should never appear and if it does then it means there is an unknown error with the gauge (and probably the module).
- LOADING (All module types): The gauge is being loaded.
- READY (All module types): The gauge is ready to be used.
- UNLOADING (Airport modules only): The airport is currently unloading.
- UNLOADED (Airport modules only): The airport is unloaded.
- TO KILL (System modules only): The system has been mark to kill.
- KILLED (System modules only): The system has been killed.
- FAILED (All module types): Something has happened that has caused the gauge to fail and not work.
- Liveview Name (Gauge modules only): This is the name of the Coherent live view.
- Liveview Status (Gauge modules only): This will be one of the following:
- IDLE
- LOADING
- READY
- OBSOLETE
- Has Gauge Callback (Gauge modules only): This will show TRUE or FALSE to indicate whether callbacks are present in the module code.
- Has Mouse Callback (Gauge modules only): This will show TRUE or FALSE to indicate whether mouse interactions are present in the module code.
- Init callback registered (System and AIrport modules only): This will show TRUE or FALSE to indicate whether an initialisation callback has been registered for the module.
- Update callback registered (System and AIrport modules only): This will show TRUE or FALSE to indicate whether an update callback has been registered for the module.
- Kill callback registered (System and AIrport modules only): This will show TRUE or FALSE to indicate whether a kill callback has been registered for the module.
At the bottom of this section you may also see an indicator to say whether the module being checked has been compiled using the Microsoft Flight Simulator 2024 SDK or a previous version.
Under these details you can find various checkboxes (depending on the module selected) with written details on the execution timings for the module, and if you click any of checkboxes, you will see a real-time performance graph:
Memory Section
This tab contains information related to how the selected module is using the available memory:
At the top of this tab you have a section giving an overview of the memory that allocation and size. It has the following option:
- Update Memory Data Frequency: This controls the polling frequency for the tab. While this tab is focused, data about the module's memory use will be gathered each "n" frames, where "n" is the value given in this input field.
The rest of this section has the following information:
- Linear Memory Size - This shows the total size of virtual memory given to the module.
- Heap Memory - This shows the size of heap memory for the module, along with the real committed memory for the heap (i.e: the physical memory that is used for the heap). The Heap Memory is a part of the Linear Memory.
- Allocated - This shows the part of the memory that has been allocated (i.e: containing data). Allocated Memory is a part of the Heap Memory.
- Not Allocated - This shows the memory that can be allocated with a
malloc
. The Not Allocated Memory is a part of the Heap Memory. - Released - This shows the memory which has been given back to the system, there is no physical memory bound to it. The Released Memory is a part of the Not Allocated Memory.
- Wasted Memory - This shows the memory which is not used by the module, but is bound to physical memory. There are multiple sources of wasted memory, some are due to the system (unallocated pages not de-committed, system data, etc…), others are caused by the memory fragmentation (pages with very little data). The rest of the Memory Debug tab can help to track this. Wasted Memory is part of the Not Allocated Memory.
- Data And Stack Memory - This shows the memory available to stack and static data. The Data And Stack Memory is part of the Linear Memory.
Under this data you have the Full Check Memory
button. Clicking this will check if the internal memory data is correct and memory allocation is working as it should. If you click this and get any message other than "Memory Is Okay", then broken memory pages will be listed further down and - if located in the heap - they will also be printed in the memory fragmentation window. You should contact DevSupport in the case of errors.
Memory Fragmentation Grid
The memory fragmentation grid contains a representation of how Heap Memory is allocated, where each grid cell is a WASM memory page:
There are five possible states that a page can have:
(grey): The page is currently de-committed (there is no physical memory bound to it).
(green): The page is committed (there is physical memory bound to it), but it currently contains no data. This page may be de-committed soon, except if this is the last block (In which case, the page will never be de-committed).
(red): The page is committed (there is physical memory bound to it), the page contains data, and is currently full.
(blue): The page is committed (there is physical memory bound to it), the page contains data, but it is not currently full.
(magenta): The page not in a valid state. You can hover over the square - and/or click on it - to show more info, and if you have pages like this then you should contact DevSupport.
If you hover over any of the page squares, you will be shown further data about the page state, including:
- An ID value to identify the page.
- How much memory is malloced on the page.
- The number of chunks that start on the page. A chunk is the result of one malloc, and the number shown includes the number of free chunks.
- The number of free chunks that start on the page. A free chunk is the result of a malloc and then a free.
If you click on any of the page squares then you can get even more information about the page state, which is shown in the window under the Memory Fragmentation Grid:
This section repeats the information that can be found by hovering and also includes:
- The start address, which is the memory location where the page starts
- A list of details about the each chunk which includes:
- an ID
- the memory address
- the size
- whether the chunk is in use or not
Note that you can click on the address or the size to copy the value to the clipboard.
Decommit Duration
At the bottom of the Memory Debug tab, you can find the Decommit Duration:
This section shows the time taken to decommit a page, giving the last decommit time along with minimum, maximum and average values. If you are experimenting any lag spikes when using the module, you can use this section to determine whether the issue is with the decommit process or not. Note that the simulation should decommit unused WASM pages automatically to prevent memory leaks and having all the available memory filled up by the module.