Skip to content

Commit e18b651

Browse files
authored
Pass up the reason for failure for telemetry. (proxy-wasm#33)
Signed-off-by: John Plevyak <jplevyak@gmail.com>
1 parent bd1c285 commit e18b651

File tree

5 files changed

+71
-47
lines changed

5 files changed

+71
-47
lines changed

include/proxy-wasm/context.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,16 @@ class WasmVm;
4747
* @param fail_open if true the plugin will pass traffic as opposed to close all streams.
4848
*/
4949
struct PluginBase {
50-
PluginBase(string_view name, string_view root_id, string_view vm_id,
50+
PluginBase(string_view name, string_view root_id, string_view vm_id, string_view runtime,
5151
string_view plugin_configuration, bool fail_open)
5252
: name_(std::string(name)), root_id_(std::string(root_id)), vm_id_(std::string(vm_id)),
53-
plugin_configuration_(plugin_configuration), fail_open_(fail_open) {}
53+
runtime_(std::string(runtime)), plugin_configuration_(plugin_configuration),
54+
fail_open_(fail_open) {}
5455

5556
const std::string name_;
5657
const std::string root_id_;
5758
const std::string vm_id_;
59+
const std::string runtime_;
5860
std::string plugin_configuration_;
5961
const bool fail_open_;
6062
const std::string &log_prefix() const { return log_prefix_; }

include/proxy-wasm/wasm.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
7171
return nullptr;
7272
}
7373
uint32_t allocContextId();
74-
bool isFailed() { return failed_; }
74+
bool isFailed() { return failed_ != FailState::Ok; }
75+
FailState fail_state() { return failed_; }
7576

7677
const std::string &code() const { return code_; }
7778
const std::string &vm_configuration() const;
@@ -115,9 +116,9 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
115116

116117
WasmForeignFunction getForeignFunction(string_view function_name);
117118

118-
void fail(string_view message) {
119+
void fail(FailState fail_state, string_view message) {
119120
error(message);
120-
failed_ = true;
121+
failed_ = fail_state;
121122
}
122123
virtual void error(string_view message) { std::cerr << message << "\n"; }
123124
virtual void unimplemented() { error("unimplemented proxy-wasm API"); }
@@ -236,7 +237,7 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
236237
std::string code_;
237238
std::string vm_configuration_;
238239
bool allow_precompiled_ = false;
239-
bool failed_ = false; // The Wasm VM has experienced a fatal error.
240+
FailState failed_ = FailState::Ok; // Wasm VM fatal error.
240241

241242
bool is_emscripten_ = false;
242243
uint32_t emscripten_metadata_major_version_ = 0;

include/proxy-wasm/wasm_vm.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ struct WasmVmIntegration {
124124
void *ptr_to_function_return) = 0;
125125
};
126126

127+
enum class FailState : int {
128+
Ok = 0,
129+
UnableToCreateVM = 1,
130+
UnableToCloneVM = 2,
131+
MissingFunction = 3,
132+
UnableToInitializeCode = 4,
133+
StartFailed = 5,
134+
ConfigureFailed = 6,
135+
RuntimeError = 7,
136+
};
137+
127138
// Wasm VM instance. Provides the low level WASM interface.
128139
class WasmVm {
129140
public:
@@ -250,24 +261,26 @@ class WasmVm {
250261
FOR_ALL_WASM_VM_IMPORTS(_REGISTER_CALLBACK)
251262
#undef _REGISTER_CALLBACK
252263

253-
bool isFailed() { return failed_; }
254-
void fail(string_view message) {
264+
bool isFailed() { return failed_ != FailState::Ok; }
265+
void fail(FailState fail_state, string_view message) {
255266
error(message);
256-
failed_ = true;
267+
failed_ = fail_state;
257268
if (fail_callback_) {
258-
fail_callback_();
269+
fail_callback_(fail_state);
259270
}
260271
}
261-
void setFailCallback(std::function<void()> fail_callback) { fail_callback_ = fail_callback; }
272+
void setFailCallback(std::function<void(FailState)> fail_callback) {
273+
fail_callback_ = fail_callback;
274+
}
262275

263276
// Integrator operations.
264277
std::unique_ptr<WasmVmIntegration> &integration() { return integration_; }
265278
void error(string_view message) { integration()->error(message); }
266279

267-
private:
280+
protected:
268281
std::unique_ptr<WasmVmIntegration> integration_;
269-
bool failed_ = false;
270-
std::function<void()> fail_callback_;
282+
FailState failed_ = FailState::Ok;
283+
std::function<void(FailState)> fail_callback_;
271284
};
272285

273286
// Thread local state set during a call into a WASM VM so that calls coming out of the

src/v8/v8.cc

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -322,20 +322,20 @@ string_view V8::getCustomSection(string_view name) {
322322
const byte_t *end = source_.get() + source_.size();
323323
while (pos < end) {
324324
if (pos + 1 > end) {
325-
fail("Failed to parse corrupted Wasm module");
325+
fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module");
326326
return "";
327327
}
328328
const auto section_type = *pos++;
329329
const auto section_len = parseVarint(pos, end);
330330
if (section_len == static_cast<uint32_t>(-1) || pos + section_len > end) {
331-
fail("Failed to parse corrupted Wasm module");
331+
fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module");
332332
return "";
333333
}
334334
if (section_type == 0 /* custom section */) {
335335
const auto section_data_start = pos;
336336
const auto section_name_len = parseVarint(pos, end);
337337
if (section_name_len == static_cast<uint32_t>(-1) || pos + section_name_len > end) {
338-
fail("Failed to parse corrupted Wasm module");
338+
fail(FailState::UnableToInitializeCode, "Failed to parse corrupted Wasm module");
339339
return "";
340340
}
341341
if (section_name_len == name.size() && ::memcmp(pos, name.data(), section_name_len) == 0) {
@@ -382,28 +382,31 @@ bool V8::link(string_view debug_name) {
382382
case wasm::EXTERN_FUNC: {
383383
auto it = host_functions_.find(std::string(module) + "." + std::string(name));
384384
if (it == host_functions_.end()) {
385-
fail(std::string("Failed to load Wasm module due to a missing import: ") +
386-
std::string(module) + "." + std::string(name));
385+
fail(FailState::UnableToInitializeCode,
386+
std::string("Failed to load Wasm module due to a missing import: ") +
387+
std::string(module) + "." + std::string(name));
387388
break;
388389
}
389390
auto func = it->second.get()->callback_.get();
390391
if (!equalValTypes(import_type->func()->params(), func->type()->params()) ||
391392
!equalValTypes(import_type->func()->results(), func->type()->results())) {
392-
fail(std::string("Failed to load Wasm module due to an import type mismatch: ") +
393-
std::string(module) + "." + std::string(name) +
394-
", want: " + printValTypes(import_type->func()->params()) + " -> " +
395-
printValTypes(import_type->func()->results()) +
396-
", but host exports: " + printValTypes(func->type()->params()) + " -> " +
397-
printValTypes(func->type()->results()));
393+
fail(FailState::UnableToInitializeCode,
394+
std::string("Failed to load Wasm module due to an import type mismatch: ") +
395+
std::string(module) + "." + std::string(name) +
396+
", want: " + printValTypes(import_type->func()->params()) + " -> " +
397+
printValTypes(import_type->func()->results()) +
398+
", but host exports: " + printValTypes(func->type()->params()) + " -> " +
399+
printValTypes(func->type()->results()));
398400
break;
399401
}
400402
imports.push_back(func);
401403
} break;
402404

403405
case wasm::EXTERN_GLOBAL: {
404406
// TODO(PiotrSikora): add support when/if needed.
405-
fail("Failed to load Wasm module due to a missing import: " + std::string(module) + "." +
406-
std::string(name));
407+
fail(FailState::UnableToInitializeCode,
408+
"Failed to load Wasm module due to a missing import: " + std::string(module) + "." +
409+
std::string(name));
407410
} break;
408411

409412
case wasm::EXTERN_MEMORY: {
@@ -565,7 +568,8 @@ void V8::getModuleFunctionImpl(string_view function_name,
565568
const wasm::Func *func = it->second.get();
566569
if (!equalValTypes(func->type()->params(), convertArgsTupleToValTypes<std::tuple<Args...>>()) ||
567570
!equalValTypes(func->type()->results(), convertArgsTupleToValTypes<std::tuple<>>())) {
568-
fail(std::string("Bad function signature for: ") + std::string(function_name));
571+
fail(FailState::UnableToInitializeCode,
572+
std::string("Bad function signature for: ") + std::string(function_name));
569573
*function = nullptr;
570574
return;
571575
}
@@ -574,8 +578,8 @@ void V8::getModuleFunctionImpl(string_view function_name,
574578
SaveRestoreContext saved_context(context);
575579
auto trap = func->call(params, nullptr);
576580
if (trap) {
577-
fail("Function: " + std::string(function_name) +
578-
" failed: " + std::string(trap->message().get(), trap->message().size()));
581+
fail(FailState::RuntimeError, "Function: " + std::string(function_name) + " failed: " +
582+
std::string(trap->message().get(), trap->message().size()));
579583
}
580584
};
581585
}
@@ -591,7 +595,8 @@ void V8::getModuleFunctionImpl(string_view function_name,
591595
const wasm::Func *func = it->second.get();
592596
if (!equalValTypes(func->type()->params(), convertArgsTupleToValTypes<std::tuple<Args...>>()) ||
593597
!equalValTypes(func->type()->results(), convertArgsTupleToValTypes<std::tuple<R>>())) {
594-
fail("Bad function signature for: " + std::string(function_name));
598+
fail(FailState::UnableToInitializeCode,
599+
"Bad function signature for: " + std::string(function_name));
595600
*function = nullptr;
596601
return;
597602
}
@@ -601,8 +606,8 @@ void V8::getModuleFunctionImpl(string_view function_name,
601606
SaveRestoreContext saved_context(context);
602607
auto trap = func->call(params, results);
603608
if (trap) {
604-
fail("Function: " + std::string(function_name) +
605-
" failed: " + std::string(trap->message().get(), trap->message().size()));
609+
fail(FailState::RuntimeError, "Function: " + std::string(function_name) + " failed: " +
610+
std::string(trap->message().get(), trap->message().size()));
606611
return R{};
607612
}
608613
R rvalue = results[0].get<typename ConvertWordTypeToUint32<R>::type>();

src/wasm.cc

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ void WasmBase::getFunctions() {
235235
#undef _GET_PROXY
236236

237237
if (!malloc_) {
238-
fail("Wasm missing malloc");
238+
fail(FailState::MissingFunction, "Wasm missing malloc");
239239
}
240240
}
241241

@@ -250,9 +250,9 @@ WasmBase::WasmBase(const std::shared_ptr<WasmHandleBase> &base_wasm_handle, Wasm
250250
wasm_vm_ = factory();
251251
}
252252
if (!wasm_vm_) {
253-
failed_ = true;
253+
failed_ = FailState::UnableToCreateVM;
254254
} else {
255-
wasm_vm_->setFailCallback([this] { failed_ = true; });
255+
wasm_vm_->setFailCallback([this](FailState fail_state) { failed_ = fail_state; });
256256
}
257257
}
258258

@@ -261,9 +261,9 @@ WasmBase::WasmBase(std::unique_ptr<WasmVm> wasm_vm, string_view vm_id, string_vi
261261
: vm_id_(std::string(vm_id)), vm_key_(std::string(vm_key)), wasm_vm_(std::move(wasm_vm)),
262262
vm_configuration_(std::string(vm_configuration)) {
263263
if (!wasm_vm_) {
264-
failed_ = true;
264+
failed_ = FailState::UnableToCreateVM;
265265
} else {
266-
wasm_vm_->setFailCallback([this] { failed_ = true; });
266+
wasm_vm_->setFailCallback([this](FailState fail_state) { failed_ = fail_state; });
267267
}
268268
}
269269

@@ -450,25 +450,26 @@ std::shared_ptr<WasmHandleBase> createWasm(std::string vm_key, std::string code,
450450
}
451451

452452
if (!wasm_handle->wasm()->initialize(code, allow_precompiled)) {
453-
wasm_handle->wasm()->fail("Failed to initialize Wasm code");
453+
wasm_handle->wasm()->fail(FailState::UnableToInitializeCode, "Failed to initialize Wasm code");
454454
return nullptr;
455455
}
456456
auto configuration_canary_handle = clone_factory(wasm_handle);
457457
if (!configuration_canary_handle) {
458-
wasm_handle->wasm()->fail("Failed to clone Base Wasm");
458+
wasm_handle->wasm()->fail(FailState::UnableToCloneVM, "Failed to clone Base Wasm");
459459
return nullptr;
460460
}
461461
if (!configuration_canary_handle->wasm()->initialize(code, allow_precompiled)) {
462-
wasm_handle->wasm()->fail("Failed to initialize Wasm code");
462+
wasm_handle->wasm()->fail(FailState::UnableToInitializeCode, "Failed to initialize Wasm code");
463463
return nullptr;
464464
}
465465
auto root_context = configuration_canary_handle->wasm()->start(plugin);
466466
if (!root_context) {
467-
configuration_canary_handle->wasm()->fail("Failed to start base Wasm");
467+
configuration_canary_handle->wasm()->fail(FailState::StartFailed, "Failed to start base Wasm");
468468
return nullptr;
469469
}
470470
if (!configuration_canary_handle->wasm()->configure(root_context, plugin)) {
471-
configuration_canary_handle->wasm()->fail("Failed to configure base Wasm plugin");
471+
configuration_canary_handle->wasm()->fail(FailState::ConfigureFailed,
472+
"Failed to configure base Wasm plugin");
472473
return nullptr;
473474
}
474475
configuration_canary_handle->kill();
@@ -484,16 +485,17 @@ createThreadLocalWasm(std::shared_ptr<WasmHandleBase> &base_wasm,
484485
}
485486
if (!wasm_handle->wasm()->initialize(wasm_handle->wasm()->code(),
486487
wasm_handle->wasm()->allow_precompiled())) {
487-
wasm_handle->wasm()->fail("Failed to initialize Wasm code");
488+
wasm_handle->wasm()->fail(FailState::UnableToInitializeCode, "Failed to initialize Wasm code");
488489
return nullptr;
489490
}
490491
ContextBase *root_context = wasm_handle->wasm()->start(plugin);
491492
if (!root_context) {
492-
base_wasm->wasm()->fail("Failed to start thread-local Wasm");
493+
base_wasm->wasm()->fail(FailState::StartFailed, "Failed to start thread-local Wasm");
493494
return nullptr;
494495
}
495496
if (!wasm_handle->wasm()->configure(root_context, plugin)) {
496-
base_wasm->wasm()->fail("Failed to configure thread-local Wasm plugin");
497+
base_wasm->wasm()->fail(FailState::ConfigureFailed,
498+
"Failed to configure thread-local Wasm plugin");
497499
return nullptr;
498500
}
499501
local_wasms[std::string(wasm_handle->wasm()->vm_key())] = wasm_handle;
@@ -519,7 +521,8 @@ getOrCreateThreadLocalWasm(std::shared_ptr<WasmHandleBase> base_wasm,
519521
if (wasm_handle) {
520522
auto root_context = wasm_handle->wasm()->getOrCreateRootContext(plugin);
521523
if (!wasm_handle->wasm()->configure(root_context, plugin)) {
522-
base_wasm->wasm()->fail("Failed to configure thread-local Wasm code");
524+
base_wasm->wasm()->fail(FailState::ConfigureFailed,
525+
"Failed to configure thread-local Wasm code");
523526
return nullptr;
524527
}
525528
return wasm_handle;

0 commit comments

Comments
 (0)