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

Side by Side Diff: src/v8.cc

Issue 768543002: [WIP] TrapHandler 2014/11/27. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years 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
« no previous file with comments | « src/runtime/runtime-typedarray.cc ('k') | test/cctest/cctest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 <signal.h>
6 #include <ucontext.h>
7
5 #include "src/v8.h" 8 #include "src/v8.h"
6 9
7 #include "src/assembler.h" 10 #include "src/assembler.h"
8 #include "src/base/once.h" 11 #include "src/base/once.h"
9 #include "src/base/platform/platform.h" 12 #include "src/base/platform/platform.h"
10 #include "src/bootstrapper.h" 13 #include "src/bootstrapper.h"
11 #include "src/compiler/pipeline.h" 14 #include "src/compiler/pipeline.h"
12 #include "src/debug.h" 15 #include "src/debug.h"
13 #include "src/deoptimizer.h" 16 #include "src/deoptimizer.h"
14 #include "src/elements.h" 17 #include "src/elements.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 FlagList::ResetAllFlags(); // Frees memory held by string arguments. 61 FlagList::ResetAllFlags(); // Frees memory held by string arguments.
59 } 62 }
60 63
61 64
62 void V8::SetReturnAddressLocationResolver( 65 void V8::SetReturnAddressLocationResolver(
63 ReturnAddressLocationResolver resolver) { 66 ReturnAddressLocationResolver resolver) {
64 StackFrame::SetReturnAddressLocationResolver(resolver); 67 StackFrame::SetReturnAddressLocationResolver(resolver);
65 } 68 }
66 69
67 70
71 // TODO(bmeurer): Move to signal-handlers.cc?
72 namespace {
73
74 struct sigaction prev_handler;
75
76
77 struct Decoder {
78 void get_modrm(uint8_t data, int* mod, int* regop, int* rm) {
79 *mod = (data >> 6) & 3;
80 *regop = (data & 0x38) >> 3;
81 *rm = (data & 7);
82 }
83
84 void get_sib(uint8_t data, int* scale, int* index, int* base) {
85 *scale = (data >> 6) & 3;
86 *index = ((data >> 3) & 7);
87 *base = (data & 7);
88 }
89
90 int right_operand(uint8_t* modrmp) {
91 int mod, regop, rm;
92 get_modrm(*modrmp, &mod, &regop, &rm);
93 switch (mod) {
94 case 0:
95 if (rm == 5) {
96 return 5;
97 } else if (rm == 4) {
98 int scale, index, base;
99 get_sib(modrmp[1], &scale, &index, &base);
100 return base == 5 ? 6 : 2;
101 } else {
102 return 1;
103 }
104 case 1:
105 return 2 + (rm == 4);
106 case 2:
107 return 5 + (rm == 4);
108 case 3:
109 return 1;
110 default:
111 break;
112 }
113 UNREACHABLE();
114 return 0;
115 }
116
117 bool Decode(uint8_t** ppc) {
118 uint8_t* pc = *ppc;
119 bool operand_word_size = false;
120 while (true) {
121 if (*pc == 0x66) { // Group 3 prefix.
122 operand_word_size = true;
123 } else if ((*pc & 0xF0) == 0x40) {
124 // Skip REX.
125 } else {
126 break; // Not a prefix - an opcode.
127 }
128 ++pc;
129 }
130 switch (*pc) {
131 case 0x0F: {
132 if (pc[1] == 0xB6) { // mov
133 }
134 break;
135 }
136 case 0xF2: {
137 if (pc[1] == 0x0F && pc[2] == 0x11) { // movsd mem,reg
138 pc += 3;
139 *ppc = pc + right_operand(pc);
140 PrintF("*** movsd mem,reg\n");
141 return true;
142 }
143 break;
144 }
145 case 0xF3: {
146 if (pc[1] == 0x0F && pc[2] == 0x11) { // movss mem,reg
147 pc += 3;
148 *ppc = pc + right_operand(pc);
149 PrintF("*** movss mem,reg\n");
150 return true;
151 }
152 break;
153 }
154 case 0x88:
155 case 0x89: { // mov mem,reg
156 ++pc;
157 *ppc = pc + right_operand(pc);
158 PrintF("*** mov mem,reg\n");
159 return true;
160 }
161 case 0xC6: { // mov mem,imm8
162 ++pc;
163 *ppc = pc + right_operand(pc) + 1;
164 PrintF("*** mov mem,imm8\n");
165 return true;
166 }
167 case 0xC7: {
168 ++pc;
169 if (operand_word_size) { // mov mem,imm16
170 *ppc = pc + right_operand(pc) + 2;
171 PrintF("*** mov mem,imm16\n");
172 } else { // mov mem,imm32
173 *ppc = pc + right_operand(pc) + 4;
174 PrintF("*** mov mem,imm32\n");
175 }
176 return true;
177 }
178 default:
179 break;
180 }
181 return false;
182 }
183 };
184
185
186 bool DecodeHeapAccess(uint8_t** ppc) {
187 Decoder decoder;
188 return decoder.Decode(ppc);
189 }
190
191
192 bool HandleFault(int signum, siginfo_t* si, ucontext_t* uc) {
193 if (signum != SIGSEGV) return false;
194 Isolate* const isolate = Isolate::UnsafeCurrent();
195 if (!isolate || !isolate->IsInUse()) {
196 // We require a fully initialized and entered isolate.
197 return false;
198 }
199 if (v8::Locker::IsActive() &&
200 !isolate->thread_manager()->IsLockedByCurrentThread()) {
201 return false;
202 }
203 if (!isolate->IsInGuardArea(si->si_addr)) return false;
204 uint8_t** ppc = reinterpret_cast<uint8_t**>(&uc->uc_mcontext.gregs[REG_RIP]);
205 if (DecodeHeapAccess(ppc)) return true;
206 PrintF("*** Unhandled fault at %p!\n", *ppc);
207 return false;
208 }
209
210
211 void FaultHandler(int signum, siginfo_t* si, void* context) {
212 if (HandleFault(signum, si, static_cast<ucontext_t*>(context))) return;
213
214 // This signal is not for any asm.js code we expect, so we need to forward
215 // the signal to the next handler. If there is no next handler (SIG_IGN or
216 // SIG_DFL), then it's time to crash. To do this, we set the signal back to
217 // its original disposition and return. This will cause the faulting op to
218 // be re-executed which will crash in the normal way. The advantage of
219 // doing this to calling _exit() is that we remove ourselves from the crash
220 // stack which improves crash reports. If there is a next handler, call it.
221 // It will either crash synchronously, fix up the instruction so that
222 // execution can continue and return, or trigger a crash by returning the
223 // signal to it's original disposition and returning.
224 //
225 // Note: the order of these tests matter.
226 if (prev_handler.sa_flags & SA_SIGINFO) {
227 prev_handler.sa_sigaction(signum, si, context);
228 } else if (prev_handler.sa_handler == SIG_DFL ||
229 prev_handler.sa_handler == SIG_IGN) {
230 sigaction(signum, &prev_handler, nullptr);
231 } else {
232 prev_handler.sa_handler(signum);
233 }
234 }
235
236
237 void InstallFaultHandler() {
238 // SA_NODEFER allows us to reenter the signal handler if we crash while
239 // handling the signal.
240 struct sigaction sa;
241 bzero(&sa, sizeof(sa));
242 sa.sa_flags = SA_SIGINFO | SA_NODEFER;
243 sa.sa_sigaction = &FaultHandler;
244 sigemptyset(&sa.sa_mask);
245 sigaction(SIGSEGV, &sa, &prev_handler);
246 }
247
248 } // namespace
249
250
68 void V8::InitializeOncePerProcessImpl() { 251 void V8::InitializeOncePerProcessImpl() {
69 FlagList::EnforceFlagImplications(); 252 FlagList::EnforceFlagImplications();
70 253
71 if (FLAG_predictable && FLAG_random_seed == 0) { 254 if (FLAG_predictable && FLAG_random_seed == 0) {
72 // Avoid random seeds in predictable mode. 255 // Avoid random seeds in predictable mode.
73 FLAG_random_seed = 12347; 256 FLAG_random_seed = 12347;
74 } 257 }
75 258
76 if (FLAG_stress_compaction) { 259 if (FLAG_stress_compaction) {
77 FLAG_force_marking_deque_overflows = true; 260 FLAG_force_marking_deque_overflows = true;
(...skipping 13 matching lines...) Expand all
91 init_fast_sqrt_function(); 274 init_fast_sqrt_function();
92 #ifdef _WIN64 275 #ifdef _WIN64
93 init_modulo_function(); 276 init_modulo_function();
94 #endif 277 #endif
95 ElementsAccessor::InitializeOncePerProcess(); 278 ElementsAccessor::InitializeOncePerProcess();
96 LOperand::SetUpCaches(); 279 LOperand::SetUpCaches();
97 compiler::Pipeline::SetUp(); 280 compiler::Pipeline::SetUp();
98 SetUpJSCallerSavedCodeData(); 281 SetUpJSCallerSavedCodeData();
99 ExternalReference::SetUp(); 282 ExternalReference::SetUp();
100 Bootstrapper::InitializeOncePerProcess(); 283 Bootstrapper::InitializeOncePerProcess();
284 InstallFaultHandler();
101 } 285 }
102 286
103 287
104 void V8::InitializeOncePerProcess() { 288 void V8::InitializeOncePerProcess() {
105 base::CallOnce(&init_once, &InitializeOncePerProcessImpl); 289 base::CallOnce(&init_once, &InitializeOncePerProcessImpl);
106 } 290 }
107 291
108 292
109 void V8::InitializePlatform(v8::Platform* platform) { 293 void V8::InitializePlatform(v8::Platform* platform) {
110 CHECK(!platform_); 294 CHECK(!platform_);
(...skipping 24 matching lines...) Expand all
135 319
136 320
137 void V8::SetSnapshotBlob(StartupData* snapshot_blob) { 321 void V8::SetSnapshotBlob(StartupData* snapshot_blob) {
138 #ifdef V8_USE_EXTERNAL_STARTUP_DATA 322 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
139 base::CallOnce(&init_snapshot_once, &SetSnapshotFromFile, snapshot_blob); 323 base::CallOnce(&init_snapshot_once, &SetSnapshotFromFile, snapshot_blob);
140 #else 324 #else
141 CHECK(false); 325 CHECK(false);
142 #endif 326 #endif
143 } 327 }
144 } } // namespace v8::internal 328 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime/runtime-typedarray.cc ('k') | test/cctest/cctest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698