Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WASM SEGV handler and test. Create and use a Makefile.base for WASM c++ compiles. #21

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions api/wasm/cpp/Makefile.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
API:=$(shell git rev-parse --show-toplevel)/api/wasm/cpp

%.wasm %.wat: %.cc ${API}/proxy_wasm_intrinsics.h ${API}/proxy_wasm_intrinsics.js
em++ -s WASM=1 -s EMIT_EMSCRIPTEN_METADATA=1 --std=c++14 -O3 -g3 -I${API} --js-library ${API}/proxy_wasm_intrinsics.js $*.cc -o $*.js
wavm-disas $*.wasm $*.wat
wavm-compile $*.wasm $*.wasm
rm -f $*.js $*.wast
chmod 644 $*.wat
5 changes: 5 additions & 0 deletions source/extensions/common/wasm/wasm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,10 @@ uint32_t httpCallHandler(void* raw_context, uint32_t uri_ptr, uint32_t uri_size,

uint32_t getTotalMemoryHandler(void*) { return 0x7FFFFFFF; }
uint32_t _emscripten_get_heap_sizeHandler(void*) { return 0x7FFFFFFF; }
void _llvm_trapHandler(void*) {
std::cerr << "llvm_trapHandler";
throw WasmException("emscripten llvm_trap");
}

void setTickPeriodMillisecondsHandler(void* raw_context, uint32_t tick_period_milliseconds) {
WASM_CONTEXT(raw_context)->setTickPeriod(std::chrono::milliseconds(tick_period_milliseconds));
Expand Down Expand Up @@ -941,6 +945,7 @@ Wasm::Wasm(absl::string_view vm, absl::string_view id, absl::string_view initial
#define _REGISTER(_fn) registerCallback(wasm_vm_.get(), #_fn, &_fn##Handler);
_REGISTER(getTotalMemory);
_REGISTER(_emscripten_get_heap_size);
_REGISTER(_llvm_trap);
#undef _REGISTER

// Calls with the "_proxy_" prefix.
Expand Down
15 changes: 1 addition & 14 deletions test/extensions/access_loggers/wasm/test_data/Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
# Note that optimizations are disabled, because optimized WASM module
# throws wavm.integerDivideByZeroOrOverflow, possibly due to an issue
# with getFunctionWavm() templates and/or their usage.
#OPT=-O3
OPT=
API=../../../../../api/wasm/cpp
include ../../../../../api/wasm/cpp/Makefile.base

all: logging.wasm

logging.wasm logging.wat: logging.cc ${API}/proxy_wasm_intrinsics.h ${API}/proxy_wasm_intrinsics.cc ${API}/proxy_wasm_intrinsics.js
em++ -s WASM=1 --std=c++14 $(OPT) -g3 -I${API} --js-library ${API}/proxy_wasm_intrinsics.js logging.cc ${API}/proxy_wasm_intrinsics.cc -o logging.js
wasm-gc logging.wasm
wavm-disas logging.wasm logging.wat
rm -f logging.js logging.wast
chmod 644 logging.wat

Binary file modified test/extensions/access_loggers/wasm/test_data/logging.wasm
Binary file not shown.
51,842 changes: 5,279 additions & 46,563 deletions test/extensions/access_loggers/wasm/test_data/logging.wat

Large diffs are not rendered by default.

24 changes: 1 addition & 23 deletions test/extensions/filters/http/wasm/test_data/Makefile
Original file line number Diff line number Diff line change
@@ -1,25 +1,3 @@
API=../../../../../../api/wasm/cpp

EMSCRIPTEN_OPT=-s WASM=1 -s EMIT_EMSCRIPTEN_METADATA=1

# Note that optimizations are disabled, because optimized WASM module
# throws wavm.integerDivideByZeroOrOverflow, possibly due to an issue
# with getFunctionWavm() templates and/or their usage.
#CXXFLAGS=--std=c++14 -O3 -g3
CXXFLAGS=--std=c++14 -g3
include ../../../../../../api/wasm/cpp/Makefile.base

all: headers.wasm async_call.wasm

headers.wasm headers.wat: headers.cc ${API}/proxy_wasm_intrinsics.h ${API}/proxy_wasm_intrinsics.cc ${API}/proxy_wasm_intrinsics.js
em++ ${EMSCRIPTEN_OPT} ${CXXFLAGS} -I${API} --js-library ${API}/proxy_wasm_intrinsics.js headers.cc ${API}/proxy_wasm_intrinsics.cc -o headers.js
wasm-gc headers.wasm
wavm-disas headers.wasm headers.wat
rm -f headers.js headers.wast
chmod 644 headers.wat

async_call.wasm async_call.wat: async_call.cc ${API}/proxy_wasm_intrinsics.h ${API}/proxy_wasm_intrinsics.cc ${API}/proxy_wasm_intrinsics.js
em++ ${EMSCRIPTEN_OPT} ${CXXFLAGS} -I${API} --js-library ${API}/proxy_wasm_intrinsics.js async_call.cc ${API}/proxy_wasm_intrinsics.cc -o async_call.js
wasm-gc async_call.wasm
wavm-disas async_call.wasm async_call.wat
rm -f async_call.js async_call.wast
chmod 644 async_call.wat
Binary file modified test/extensions/filters/http/wasm/test_data/async_call.wasm
Binary file not shown.
59,612 changes: 5,259 additions & 54,353 deletions test/extensions/filters/http/wasm/test_data/async_call.wat

Large diffs are not rendered by default.

Binary file modified test/extensions/filters/http/wasm/test_data/headers.wasm
Binary file not shown.
51,839 changes: 5,276 additions & 46,563 deletions test/extensions/filters/http/wasm/test_data/headers.wat

Large diffs are not rendered by default.

21 changes: 2 additions & 19 deletions test/extensions/wasm/test_data/Makefile
Original file line number Diff line number Diff line change
@@ -1,20 +1,3 @@
API=../../../../api/wasm/cpp
include ../../../../api/wasm/cpp/Makefile.base

EMSCRIPTEN_OPT=-s WASM=1 -s EMIT_EMSCRIPTEN_METADATA=1
CXXFLAGS=--std=c++14 -O3 -g3

all: logging.wasm bad_signature.wasm

logging.wasm logging.wat: logging.cc ${API}/proxy_wasm_intrinsics.h ${API}/proxy_wasm_intrinsics.js
em++ ${EMSCRIPTEN_OPT} ${CXXFLAGS} -I${API} --js-library ${API}/proxy_wasm_intrinsics.js logging.cc -o logging.js
wavm-disas logging.wasm logging.wat
wavm-compile logging.wasm logging.wasm
rm -f logging.js logging.wast
chmod 644 logging.wat

bad_signature.wasm bad_signature.wat: bad_signature.cc ${API}/proxy_wasm_intrinsics.h ${API}/proxy_wasm_intrinsics.js
em++ ${EMSCRIPTEN_OPT} ${CXXFLAGS} -I${API} --js-library ${API}/proxy_wasm_intrinsics.js bad_signature.cc -o bad_signature.js
wavm-disas bad_signature.wasm bad_signature.wat
wavm-compile bad_signature.wasm bad_signature.wasm
rm -f bad_signature.js bad_signature.wast
chmod 644 bad_signature.wat
all: logging.wasm bad_signature.wasm segv.wasm
12 changes: 12 additions & 0 deletions test/extensions/wasm/test_data/segv.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// NOLINT(namespace-envoy)
#include <string>

#include "proxy_wasm_intrinsics.h"

static int *badptr = nullptr;

extern "C" EMSCRIPTEN_KEEPALIVE void proxy_onStart() {
logError("before badptr");
*badptr = 1;
logError("after badptr");
}
19 changes: 19 additions & 0 deletions test/extensions/wasm/wasm_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ TEST(WasmTest, BadSignature) {
"Bad function signature for: _proxy_onConfigure");
}

TEST(WasmTest, Segv) {
Stats::IsolatedStoreImpl stats_store;
Api::ApiPtr api = Api::createApiForTest(stats_store);
Upstream::MockClusterManager cluster_manager;
Event::SimulatedTimeSystem time_system;
Event::DispatcherImpl dispatcher(time_system, *api);
auto wasm = std::make_unique<Extensions::Common::Wasm::Wasm>("envoy.wasm.vm.wavm", "", "",
cluster_manager, dispatcher);
EXPECT_NE(wasm, nullptr);
const auto code = TestEnvironment::readFileToStringForTest(TestEnvironment::substitute(
"{{ test_rundir }}/test/extensions/wasm/test_data/segv.wasm"));
EXPECT_FALSE(code.empty());
auto context = std::make_unique<TestContext>(wasm.get());
EXPECT_CALL(*context, scriptLog(spdlog::level::err, Eq("before badptr")));
EXPECT_TRUE(wasm->initialize(code, "<test>", false));
wasm->setGeneralContext(std::move(context));
EXPECT_THROW_WITH_MESSAGE(wasm->start(), Extensions::Common::Wasm::WasmException, "emscripten llvm_trap");
}

} // namespace Wasm
} // namespace Extensions
} // namespace Envoy