Arbitrary function signature to add some content to callstack.
| 47 | |
| 48 | // Arbitrary function signature to add some content to callstack. |
| 49 | void __attribute__((noinline)) bar(int = 0, char * = 0, double = 0) { |
| 50 | if (1 == 2) |
| 51 | MYASSERT(2 == 1, "World falls apart!"); |
| 52 | else |
| 53 | MYASSERT(1 == 1, ""); |
| 54 | |
| 55 | int flags = EM_LOG_NO_PATHS | EM_LOG_JS_STACK | EM_LOG_FUNC_PARAMS; |
| 56 | |
| 57 | // We can programmatically get the callstack. |
| 58 | // 1. Ask for callstack length: |
| 59 | int nbytes = emscripten_get_callstack(flags, 0, 0); |
| 60 | // 2. Allocate temp memory to hold the callstack. |
| 61 | char *callstack = new char[nbytes]; |
| 62 | // 3. Obtain it. |
| 63 | // 4. Do something with the callstack string. |
| 64 | |
| 65 | emscripten_get_callstack(flags, callstack, nbytes); |
| 66 | |
| 67 | /* The callstack should be something like |
| 68 | at bar(int, char*, double) (src.cpp.o.js:5383:12) |
| 69 | at void Foo<int>() (src.cpp.o.js:5417:4) |
| 70 | at main() (src.cpp.o.js:5404:2) |
| 71 | at Object.callMain (src.cpp.o.js:71344:30) |
| 72 | at doRun (src.cpp.o.js:71383:25) |
| 73 | at run (src.cpp.o.js:71396:5) |
| 74 | at Object.<anonymous> (src.cpp.o.js:71439:1) |
| 75 | at Module._compile (module.js:456:26) |
| 76 | |
| 77 | but the line numbers will greatly vary depending on the mode we are compiling in, so cannot test with direct string comparison. */ |
| 78 | |
| 79 | MYASSERT(!!strstr(callstack, ".js:"), "Callstack was %s!", callstack); |
| 80 | MYASSERT(!!strstr(callstack, "bar(int, char*, double)"), "Callstack was %s!", callstack); |
| 81 | MYASSERT(!!strstr(callstack, "void Foo<int>()"), "Callstack was %s!", callstack); |
| 82 | |
| 83 | // 5. Clean up. |
| 84 | delete[] callstack; |
| 85 | |
| 86 | // Test that obtaining a truncated callstack works. (https://github.com/emscripten-core/emscripten/issues/2171) |
| 87 | const size_t callstack_buf_len = 50; |
| 88 | char *buffer = new char[callstack_buf_len+1]; |
| 89 | buffer[callstack_buf_len] = 0x01; // Magic sentinel that should not change its value. |
| 90 | emscripten_get_callstack(EM_LOG_C_STACK | EM_LOG_NO_PATHS | EM_LOG_FUNC_PARAMS, buffer, callstack_buf_len); |
| 91 | MYASSERT(!!strstr(buffer, "bar(int,"), "Truncated callstack was %s!", buffer); |
| 92 | MYASSERT(buffer[callstack_buf_len] == 0x01, ""); |
| 93 | delete[] buffer; |
| 94 | |
| 95 | // Or alternatively use a fixed-size buffer for the callstack (and get a truncated output if it was too small). |
| 96 | char str[1024]; |
| 97 | emscripten_get_callstack(EM_LOG_NO_PATHS | EM_LOG_JS_STACK, str, 1024); |
| 98 | |
| 99 | // TODO(sbc): should we try to revive these checks? The callstacks don't look quite like |
| 100 | // this in the wasm world and we already have coverage above I think? |
| 101 | #if 0 |
| 102 | /* With EM_LOG_JS_STACK, the callstack will be |
| 103 | at __Z3bariPcd (src.cpp.o.js:5394:12) |
| 104 | at __Z3FooIiEvv (src.cpp.o.js:5417:4) |
| 105 | at Object._main (src.cpp.o.js:5404:2) |
| 106 | at Object.callMain (src.cpp.o.js:71344:30) |