Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: test/cctest/wasm/test-wasm-trap-position.cc

Issue 1924253002: [wasm] Patch trapping position into stack trace (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@pass-wasm-position-to-runtime
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/wasm/wasm-macro-gen.h" 5 #include "src/wasm/wasm-macro-gen.h"
6 6
7 #include "test/cctest/cctest.h" 7 #include "test/cctest/cctest.h"
8 #include "test/cctest/compiler/value-helper.h" 8 #include "test/cctest/compiler/value-helper.h"
9 #include "test/cctest/wasm/test-signatures.h" 9 #include "test/cctest/wasm/test-signatures.h"
10 #include "test/cctest/wasm/wasm-run-utils.h" 10 #include "test/cctest/wasm/wasm-run-utils.h"
(...skipping 13 matching lines...) Expand all
24 const char* exp_ = (exp); \ 24 const char* exp_ = (exp); \
25 const char* found_ = (found); \ 25 const char* found_ = (found); \
26 DCHECK_NOT_NULL(exp); \ 26 DCHECK_NOT_NULL(exp); \
27 if (V8_UNLIKELY(found_ == nullptr || strcmp(exp_, found_) != 0)) { \ 27 if (V8_UNLIKELY(found_ == nullptr || strcmp(exp_, found_) != 0)) { \
28 V8_Fatal(__FILE__, __LINE__, \ 28 V8_Fatal(__FILE__, __LINE__, \
29 "Check failed: (%s) != (%s) ('%s' vs '%s').", #exp, #found, \ 29 "Check failed: (%s) != (%s) ('%s' vs '%s').", #exp, #found, \
30 exp_, found_ ? found_ : "<null>"); \ 30 exp_, found_ ? found_ : "<null>"); \
31 } \ 31 } \
32 } while (0) 32 } while (0)
33 33
34 void PrintStackTrace(v8::Local<v8::StackTrace> stack) {
35 printf("Stack Trace (length %d):\n", stack->GetFrameCount());
36 for (int i = 0, e = stack->GetFrameCount(); i != e; ++i) {
37 v8::Local<v8::StackFrame> frame = stack->GetFrame(i);
38 v8::Local<v8::String> func = frame->GetFunctionName();
39 if (frame->IsWasm()) {
40 printf("[%d] (<WASM>) %s:%d\n", i,
41 func.IsEmpty() ? "<null>" : *v8::String::Utf8Value(func),
42 frame->GetWasmByteOffset());
43 } else {
44 v8::Local<v8::String> script = frame->GetScriptName();
45 printf("[%d] (%s) %s:%d:%d\n", i,
46 script.IsEmpty() ? "<null>" : *v8::String::Utf8Value(script),
47 func.IsEmpty() ? "<null>" : *v8::String::Utf8Value(func),
48 frame->GetLineNumber(), frame->GetColumn());
49 }
50 }
51 }
52
53 struct ExceptionInfo { 34 struct ExceptionInfo {
54 const char* funcName; 35 const char* func_name_;
55 int lineNr; 36 bool is_wasm_;
37 int position_;
56 }; 38 };
57 39
58 template <int N> 40 template <int N>
59 void CheckExceptionInfos(Isolate* isolate, Handle<Object> exc, 41 void CheckExceptionInfos(Isolate* isolate, Handle<Object> exc,
60 const ExceptionInfo (&excInfos)[N]) { 42 const ExceptionInfo (&excInfos)[N]) {
61 // Check that it's indeed an Error object. 43 // Check that it's indeed an Error object.
62 CHECK(Object::IsErrorObject(isolate, exc)); 44 CHECK(Object::IsErrorObject(isolate, exc));
63 45
64 // Extract stack frame from the exception. 46 // Extract stack frame from the exception.
65 Local<v8::Value> localExc = Utils::ToLocal(exc); 47 Local<v8::Value> localExc = Utils::ToLocal(exc);
66 v8::Local<v8::StackTrace> stack = v8::Exception::GetStackTrace(localExc); 48 v8::Local<v8::StackTrace> stack = v8::Exception::GetStackTrace(localExc);
67 PrintStackTrace(stack);
68 CHECK(!stack.IsEmpty()); 49 CHECK(!stack.IsEmpty());
69 CHECK_EQ(N, stack->GetFrameCount()); 50 CHECK_EQ(N, stack->GetFrameCount());
70 51
71 for (int frameNr = 0; frameNr < N; ++frameNr) { 52 for (int frameNr = 0; frameNr < N; ++frameNr) {
72 v8::Local<v8::StackFrame> frame = stack->GetFrame(frameNr); 53 v8::Local<v8::StackFrame> frame = stack->GetFrame(frameNr);
73 v8::String::Utf8Value funName(frame->GetFunctionName()); 54 v8::String::Utf8Value funName(frame->GetFunctionName());
74 CHECK_CSTREQ(excInfos[frameNr].funcName, *funName); 55 CHECK_CSTREQ(excInfos[frameNr].func_name_, *funName);
75 CHECK_EQ(excInfos[frameNr].lineNr, frame->GetLineNumber()); 56 CHECK_EQ(excInfos[frameNr].is_wasm_, frame->IsWasm());
57 if (excInfos[frameNr].is_wasm_) {
58 CHECK_EQ(excInfos[frameNr].position_, frame->GetWasmByteOffset());
59 } else {
60 CHECK_EQ(excInfos[frameNr].position_, frame->GetLineNumber());
61 }
76 } 62 }
77 } 63 }
78 64
79 } // namespace 65 } // namespace
80 66
81 // Call from JS to WASM to JS and throw an Error from JS. 67 // Trigger a trap for executing unreachable.
82 TEST(CollectDetailedWasmStack_ExplicitThrowFromJs) { 68 TEST(Unreachable) {
83 TestSignatures sigs; 69 TestSignatures sigs;
84 TestingModule module; 70 TestingModule module;
85 71
86 // Initialize WasmFunctionCompiler first, since it sets up the HandleScope. 72 WasmFunctionCompiler comp1(sigs.v_v(), &module,
87 WasmFunctionCompiler comp1(sigs.v_v(), &module); 73 ArrayVector("exec_unreachable"));
88 74 // Set the execution context, such that a runtime error can be thrown.
89 uint32_t js_throwing_index = module.AddJsFunction( 75 comp1.SetModuleContext();
90 sigs.v_v(), 76 BUILD(comp1, WASM_UNREACHABLE);
91 "(function js() {\n function a() {\n throw new Error(); };\n a(); })");
92
93 BUILD(comp1, WASM_CALL_FUNCTION0(js_throwing_index));
94 uint32_t wasm_index = comp1.CompileAndAdd(); 77 uint32_t wasm_index = comp1.CompileAndAdd();
95 78
96 WasmFunctionCompiler comp2(sigs.v_v(), &module); 79 Handle<JSFunction> js_wasm_wrapper = module.WrapCode(wasm_index);
97 BUILD(comp2, WASM_CALL_FUNCTION0(wasm_index));
98 uint32_t wasm_index_2 = comp2.CompileAndAdd();
99
100 Handle<JSFunction> js_wasm_wrapper = module.WrapCode(wasm_index_2);
101 80
102 Handle<JSFunction> js_trampoline = Handle<JSFunction>::cast( 81 Handle<JSFunction> js_trampoline = Handle<JSFunction>::cast(
103 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 82 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
104 CompileRun("(function callFn(fn) { fn(); })")))); 83 CompileRun("(function callFn(fn) { fn(); })"))));
105 84
106 Isolate* isolate = js_wasm_wrapper->GetIsolate(); 85 Isolate* isolate = js_wasm_wrapper->GetIsolate();
107 isolate->SetCaptureStackTraceForUncaughtExceptions(true, 10, 86 isolate->SetCaptureStackTraceForUncaughtExceptions(true, 10,
108 v8::StackTrace::kOverview); 87 v8::StackTrace::kOverview);
109 Handle<Object> global(isolate->context()->global_object(), isolate); 88 Handle<Object> global(isolate->context()->global_object(), isolate);
110 MaybeHandle<Object> maybe_exc; 89 MaybeHandle<Object> maybe_exc;
111 Handle<Object> args[] = {js_wasm_wrapper}; 90 Handle<Object> args[] = {js_wasm_wrapper};
112 MaybeHandle<Object> returnObjMaybe = 91 MaybeHandle<Object> returnObjMaybe =
113 Execution::TryCall(isolate, js_trampoline, global, 1, args, &maybe_exc); 92 Execution::TryCall(isolate, js_trampoline, global, 1, args, &maybe_exc);
114 CHECK(returnObjMaybe.is_null()); 93 CHECK(returnObjMaybe.is_null());
115 94
116 // Line number is 1-based, with 0 == kNoLineNumberInfo.
117 ExceptionInfo expected_exceptions[] = { 95 ExceptionInfo expected_exceptions[] = {
118 {"a", 3}, // Prevent clang-format changes. 96 {"exec_unreachable", true, 1}, // Prevent clang-format changes.
titzer 2016/04/28 12:07:59 We usually just do // -- and then // -- for the ne
Clemens Hammacher 2016/04/28 12:32:12 OK, changed it anyway.
119 {"js", 4}, // - 97 {"callFn", false, 1}};
120 {"<WASM UNNAMED>", 0}, // -
121 {"<WASM UNNAMED>", 0}, // -
122 {"callFn", 1}};
123 CheckExceptionInfos(isolate, maybe_exc.ToHandleChecked(), 98 CheckExceptionInfos(isolate, maybe_exc.ToHandleChecked(),
124 expected_exceptions); 99 expected_exceptions);
125 } 100 }
126 101
127 // Trigger a trap in WASM, stack should be JS -> WASM -> WASM. 102 // Trigger a trap for loading from out-of-bounds.
128 TEST(CollectDetailedWasmStack_WasmError) { 103 TEST(IllegalLoad) {
129 TestSignatures sigs; 104 TestSignatures sigs;
130 TestingModule module; 105 TestingModule module;
131 106
132 WasmFunctionCompiler comp1(sigs.i_v(), &module, 107 WasmFunctionCompiler comp1(sigs.v_v(), &module, ArrayVector("mem_oob"));
133 ArrayVector("exec_unreachable"));
134 // Set the execution context, such that a runtime error can be thrown. 108 // Set the execution context, such that a runtime error can be thrown.
135 comp1.SetModuleContext(); 109 comp1.SetModuleContext();
136 BUILD(comp1, WASM_UNREACHABLE); 110 BUILD(comp1, WASM_IF(WASM_ONE,
111 WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V_1(-3))));
137 uint32_t wasm_index = comp1.CompileAndAdd(); 112 uint32_t wasm_index = comp1.CompileAndAdd();
138 113
139 WasmFunctionCompiler comp2(sigs.i_v(), &module, 114 WasmFunctionCompiler comp2(sigs.v_v(), &module, ArrayVector("call_mem_oob"));
140 ArrayVector("call_exec_unreachable")); 115 // Insert a NOP such that the position of the call is not one.
141 BUILD(comp2, WASM_CALL_FUNCTION0(wasm_index)); 116 BUILD(comp2, WASM_NOP, WASM_CALL_FUNCTION0(wasm_index));
142 uint32_t wasm_index_2 = comp2.CompileAndAdd(); 117 uint32_t wasm_index_2 = comp2.CompileAndAdd();
143 118
144 Handle<JSFunction> js_wasm_wrapper = module.WrapCode(wasm_index_2); 119 Handle<JSFunction> js_wasm_wrapper = module.WrapCode(wasm_index_2);
145 120
146 Handle<JSFunction> js_trampoline = Handle<JSFunction>::cast( 121 Handle<JSFunction> js_trampoline = Handle<JSFunction>::cast(
147 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( 122 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
148 CompileRun("(function callFn(fn) { fn(); })")))); 123 CompileRun("(function callFn(fn) { fn(); })"))));
149 124
150 Isolate* isolate = js_wasm_wrapper->GetIsolate(); 125 Isolate* isolate = js_wasm_wrapper->GetIsolate();
151 isolate->SetCaptureStackTraceForUncaughtExceptions(true, 10, 126 isolate->SetCaptureStackTraceForUncaughtExceptions(true, 10,
152 v8::StackTrace::kOverview); 127 v8::StackTrace::kOverview);
153 Handle<Object> global(isolate->context()->global_object(), isolate); 128 Handle<Object> global(isolate->context()->global_object(), isolate);
154 MaybeHandle<Object> maybe_exc; 129 MaybeHandle<Object> maybe_exc;
155 Handle<Object> args[] = {js_wasm_wrapper}; 130 Handle<Object> args[] = {js_wasm_wrapper};
156 MaybeHandle<Object> maybe_return_obj = 131 MaybeHandle<Object> returnObjMaybe =
157 Execution::TryCall(isolate, js_trampoline, global, 1, args, &maybe_exc); 132 Execution::TryCall(isolate, js_trampoline, global, 1, args, &maybe_exc);
158 CHECK(maybe_return_obj.is_null()); 133 CHECK(returnObjMaybe.is_null());
159 134
160 // Line number is 1-based, with 0 == kNoLineNumberInfo. 135 // Line number is 1-based, with 0 == kNoLineNumberInfo.
161 ExceptionInfo expected_exceptions[] = { 136 ExceptionInfo expected_exceptions[] = {
162 {"exec_unreachable", 0}, // Prevent clang-format changes. 137 {"mem_oob", true, 4}, // Prevent clang-format changes.
163 {"call_exec_unreachable", 0}, // - 138 {"call_mem_oob", true, 2}, // -
164 {"callFn", 1}}; 139 {"callFn", false, 1}};
165 CheckExceptionInfos(isolate, maybe_exc.ToHandleChecked(), 140 CheckExceptionInfos(isolate, maybe_exc.ToHandleChecked(),
166 expected_exceptions); 141 expected_exceptions);
167 } 142 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698