Skip to content

Commit

Permalink
improve instrumentation for memory leak detection
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelsadok committed Jul 6, 2022
1 parent b23264e commit 40979dc
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 20 deletions.
9 changes: 9 additions & 0 deletions cpp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,12 @@ To compile your application you need to link against the libfibre binary (`-L/pa
- Fibre currently targets C++11 to maximize compatibility with other projects
- Notes on platform independent programming:
- Don't use the keyword `interface` (defined as a macro on Windows in `rpc.h`)

# Debugging Memory Leaks in WASM

This works only in JS, not in dart:

- Add `-fsanitize=leak` to CFLAGS
- Add `-sINITIAL_MEMORY=104857600` to LDFLAGS
- Compile
- In example.html press "Leak Check"
24 changes: 24 additions & 0 deletions cpp/libfibre.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,3 +637,27 @@ void libfibre_run_tasks(LibFibreCtx* ctx, LibFibreTask* tasks, size_t n_tasks, L
*out_tasks = ctx->shadow_task_queue.data();
*n_out_tasks = ctx->shadow_task_queue.size();
}


extern "C" {
#if defined(__has_feature)
# if __has_feature(address_sanitizer)
# define LEAK_CHECK 1
# else
# define LEAK_CHECK 0
# endif
#else
# define LEAK_CHECK 0
#endif

#if LEAK_CHECK
#include <sanitizer/lsan_interface.h>
FIBRE_PUBLIC void do_leak_check() {
__lsan_do_recoverable_leak_check();
}
#else
FIBRE_PUBLIC int do_leak_check() {
return 0;
}
#endif
}
10 changes: 10 additions & 0 deletions js/example.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<body>
<h1 id="statusText">not connected</h1>
<button id="connectBtn" disabled>Connect...</button>
<button id="leakBtn" disabled>Leak check</button>
<script type="module">
import { fibreOpen } from './fibre.js';

Expand All @@ -27,6 +28,15 @@ <h1 id="statusText">not connected</h1>

document.getElementById("connectBtn").onclick = showDialog;
document.getElementById("connectBtn").removeAttribute('disabled');

document.getElementById("leakBtn").onclick = (obj) => {
domain._libfibre.wasm.Module._do_leak_check();

const addr = domain._libfibre.wasm.Module._malloc(1000);
console.log("got addr", addr)
domain._libfibre.wasm.Module._free(addr);
};
document.getElementById("leakBtn").removeAttribute('disabled');
});
</script>
</body>
Expand Down
46 changes: 26 additions & 20 deletions js/fibre.js
Original file line number Diff line number Diff line change
Expand Up @@ -910,28 +910,34 @@ class Domain {
}
}

export function fibreOpen(log_verbosity = 5) {
export function fibreOpen(log_verbosity = 3) {
return new Promise(async (resolve) => {
let Module = {
instantiateWasm: async (info, receiveInstance) => {
const isWebpack = typeof __webpack_require__ === 'function';
const wasmPath = isWebpack ? (await import("!!file-loader!./libfibre-wasm.wasm")).default
: "./libfibre-wasm.wasm";

let result;
if (typeof navigator === 'object') {
// Running in browser
const response = fetch(wasmPath, { credentials: 'same-origin' });
result = await WebAssembly.instantiateStreaming(response, info);
} else {
// Running in bare NodeJS
const fsPromises = (await import('fs/promises')).default;
const response = await fsPromises.readFile('/Data/Projects/fibre/js/libfibre-wasm.wasm');
result = await WebAssembly.instantiate(response, info);
}
receiveInstance(result['instance']);
return {};
}
// instantiateWasm: async (info, receiveInstance) => {
// const isWebpack = typeof __webpack_require__ === 'function';
// const wasmPath = isWebpack ? (await import("!!file-loader!./libfibre-wasm.wasm")).default
// : "./libfibre-wasm.wasm";
//
// let instantiationResult;
// var arrayBufferResult;
// if (typeof navigator === 'object') {
// // Running in browser
// const response = fetch(wasmPath, { credentials: 'same-origin' });
// arrayBufferResult = (await response).clone().arrayBuffer();
// instantiationResult = await WebAssembly.instantiateStreaming(response, info);
// console.log(instantiationResult);
// //arrayBufferResult = (await response).clone().arrayBuffer();
// } else {
// // Running in bare NodeJS
// const fsPromises = (await import('fs/promises')).default;
// const response = await fsPromises.readFile('/Data/Projects/fibre/js/libfibre-wasm.wasm');
// instantiationResult = await WebAssembly.instantiate(response, info);
// }
//
// //wasmOffsetConverter = new WasmOffsetConverter(new Uint8Array(arrayBufferResult), instantiationResult.module);
// receiveInstance(instantiationResult['instance'], null, arrayBufferResult);
// return {};
// }
};
Module = await wasm(Module);
await Module.ready;
Expand Down

0 comments on commit 40979dc

Please sign in to comment.