|
17 | 17 | #include "include/proxy-wasm/wasm_vm.h"
|
18 | 18 |
|
19 | 19 | #include <cstdlib>
|
| 20 | +#include <iomanip> |
20 | 21 | #include <iostream>
|
21 | 22 | #include <map>
|
22 | 23 | #include <memory>
|
23 | 24 | #include <optional>
|
| 25 | +#include <sstream> |
24 | 26 | #include <unordered_map>
|
25 | 27 | #include <utility>
|
26 | 28 | #include <vector>
|
|
42 | 44 | #include "WAVM/Runtime/Intrinsics.h"
|
43 | 45 | #include "WAVM/Runtime/Linker.h"
|
44 | 46 | #include "WAVM/Runtime/Runtime.h"
|
| 47 | +#include "WAVM/RuntimeABI/RuntimeABI.h" |
45 | 48 | #include "WAVM/WASM/WASM.h"
|
46 | 49 | #include "WAVM/WASTParse/WASTParse.h"
|
47 | 50 |
|
@@ -90,16 +93,37 @@ namespace {
|
90 | 93 | WAVM::Runtime::catchRuntimeExceptions( \
|
91 | 94 | [&] { _x; }, \
|
92 | 95 | [&](WAVM::Runtime::Exception *exception) { \
|
93 |
| - auto description = describeException(exception); \ |
94 |
| - _wavm->fail(FailState::RuntimeError, \ |
95 |
| - "Function: " + std::string(function_name) + " failed: " + description); \ |
96 |
| - destroyException(exception); \ |
| 96 | + _wavm->fail(FailState::RuntimeError, getFailMessage(function_name, exception)); \ |
97 | 97 | throw std::exception(); \
|
98 | 98 | }); \
|
99 | 99 | } catch (...) { \
|
100 | 100 | } \
|
101 | 101 | } while (0)
|
102 | 102 |
|
| 103 | +std::string getFailMessage(std::string_view function_name, WAVM::Runtime::Exception *exception) { |
| 104 | + std::string message = "Function " + std::string(function_name) + |
| 105 | + " failed: " + WAVM::Runtime::describeExceptionType(exception->type) + |
| 106 | + "\nProxy-Wasm plugin in-VM backtrace:\n"; |
| 107 | + std::vector<std::string> callstack_descriptions = |
| 108 | + WAVM::Runtime::describeCallStack(exception->callStack); |
| 109 | + |
| 110 | + // Since the first frame is on host and useless for developers, e.g.: `host!envoy+112901013` |
| 111 | + // we start with index 1 here |
| 112 | + for (size_t i = 1; i < callstack_descriptions.size(); i++) { |
| 113 | + std::ostringstream oss; |
| 114 | + std::string description = callstack_descriptions[i]; |
| 115 | + if (description.find("wasm!") == std::string::npos) { |
| 116 | + // end of WASM's call stack |
| 117 | + break; |
| 118 | + } |
| 119 | + oss << std::setw(3) << std::setfill(' ') << std::to_string(i); |
| 120 | + message += oss.str() + ": " + description + "\n"; |
| 121 | + } |
| 122 | + |
| 123 | + WAVM::Runtime::destroyException(exception); |
| 124 | + return message; |
| 125 | +} |
| 126 | + |
103 | 127 | struct WasmUntaggedValue : public WAVM::IR::UntaggedValue {
|
104 | 128 | WasmUntaggedValue() = default;
|
105 | 129 | WasmUntaggedValue(I32 inI32) { i32 = inI32; }
|
|
0 commit comments