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

Side by Side Diff: test/cctest/test-log-stack-tracer.cc

Issue 3436006: Enhance SafeStackFrameIterator to avoid triggering assertions in debug mode. (Closed)
Patch Set: Created 10 years, 3 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
« no previous file with comments | « src/x64/frames-x64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 } 199 }
200 200
201 201
202 static Handle<JSFunction> CompileFunction(const char* source) { 202 static Handle<JSFunction> CompileFunction(const char* source) {
203 Handle<JSFunction> result(JSFunction::cast( 203 Handle<JSFunction> result(JSFunction::cast(
204 *v8::Utils::OpenHandle(*Script::Compile(String::New(source))))); 204 *v8::Utils::OpenHandle(*Script::Compile(String::New(source)))));
205 return result; 205 return result;
206 } 206 }
207 207
208 208
209 static Local<Value> GetGlobalProperty(const char* name) { 209 static void CheckJSFunctionAtAddress(const char* func_name, Address addr) {
210 return env->Global()->Get(String::New(name)); 210 i::Object* obj = i::HeapObject::FromAddress(addr);
211 }
212
213
214 static Handle<JSFunction> GetGlobalJSFunction(const char* name) {
215 Handle<JSFunction> result(JSFunction::cast(
216 *v8::Utils::OpenHandle(*GetGlobalProperty(name))));
217 return result;
218 }
219
220
221 static void CheckObjectIsJSFunction(const char* func_name,
222 Address addr) {
223 i::Object* obj = reinterpret_cast<i::Object*>(addr);
224 CHECK(obj->IsJSFunction()); 211 CHECK(obj->IsJSFunction());
225 CHECK(JSFunction::cast(obj)->shared()->name()->IsString()); 212 CHECK(JSFunction::cast(obj)->shared()->name()->IsString());
226 i::SmartPointer<char> found_name = 213 i::SmartPointer<char> found_name =
227 i::String::cast( 214 i::String::cast(
228 JSFunction::cast( 215 JSFunction::cast(
229 obj)->shared()->name())->ToCString(); 216 obj)->shared()->name())->ToCString();
230 CHECK_EQ(func_name, *found_name); 217 CHECK_EQ(func_name, *found_name);
231 } 218 }
232 219
233 220
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 CHECK(!func.is_null()); 284 CHECK(!func.is_null());
298 func->shared()->set_name(*NewString(func_name)); 285 func->shared()->set_name(*NewString(func_name));
299 286
300 #ifdef DEBUG 287 #ifdef DEBUG
301 v8::internal::Code* func_code = func->code(); 288 v8::internal::Code* func_code = func->code();
302 CHECK(func_code->IsCode()); 289 CHECK(func_code->IsCode());
303 func_code->Print(); 290 func_code->Print();
304 #endif 291 #endif
305 292
306 SetGlobalProperty(func_name, v8::ToApi<Value>(func)); 293 SetGlobalProperty(func_name, v8::ToApi<Value>(func));
307 CHECK_EQ(*func, *GetGlobalJSFunction(func_name));
308 } 294 }
309 295
310 296
311 // This test verifies that stack tracing works when called during 297 // This test verifies that stack tracing works when called during
312 // execution of a native function called from JS code. In this case, 298 // execution of a native function called from JS code. In this case,
313 // StackTracer uses Top::c_entry_fp as a starting point for stack 299 // StackTracer uses Top::c_entry_fp as a starting point for stack
314 // walking. 300 // walking.
315 TEST(CFromJSStackTrace) { 301 TEST(CFromJSStackTrace) {
316 TickSample sample; 302 TickSample sample;
317 InitTraceEnv(&sample); 303 InitTraceEnv(&sample);
318 304
319 InitializeVM(); 305 InitializeVM();
320 v8::HandleScope scope; 306 v8::HandleScope scope;
321 // Create global function JSFuncDoTrace which calls 307 // Create global function JSFuncDoTrace which calls
322 // extension function trace() with the current frame pointer value. 308 // extension function trace() with the current frame pointer value.
323 CreateTraceCallerFunction("JSFuncDoTrace", "trace"); 309 CreateTraceCallerFunction("JSFuncDoTrace", "trace");
324 Local<Value> result = CompileRun( 310 Local<Value> result = CompileRun(
325 "function JSTrace() {" 311 "function JSTrace() {"
326 " JSFuncDoTrace();" 312 " JSFuncDoTrace();"
327 "};\n" 313 "};\n"
328 "JSTrace();\n" 314 "JSTrace();\n"
329 "true;"); 315 "true;");
330 CHECK(!result.IsEmpty()); 316 CHECK(!result.IsEmpty());
331 // When stack tracer is invoked, the stack should look as follows: 317 // When stack tracer is invoked, the stack should look as follows:
332 // script [JS] 318 // script [JS]
333 // JSTrace() [JS] 319 // JSTrace() [JS]
334 // JSFuncDoTrace() [JS] [captures EBP value and encodes it as Smi] 320 // JSFuncDoTrace() [JS] [captures EBP value and encodes it as Smi]
335 // trace(EBP encoded as Smi) [native (extension)] 321 // trace(EBP) [native (extension)]
336 // DoTrace(EBP) [native] 322 // DoTrace(EBP) [native]
337 // StackTracer::Trace 323 // StackTracer::Trace
338 CHECK_GT(sample.frames_count, 1); 324 CHECK_GT(sample.frames_count, 1);
339 // Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace" 325 // Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
340 CheckObjectIsJSFunction("JSFuncDoTrace", sample.stack[0]); 326 CheckJSFunctionAtAddress("JSFuncDoTrace", sample.stack[0]);
341 CheckObjectIsJSFunction("JSTrace", sample.stack[1]); 327 CheckJSFunctionAtAddress("JSTrace", sample.stack[1]);
342 } 328 }
343 329
344 330
345 // This test verifies that stack tracing works when called during 331 // This test verifies that stack tracing works when called during
346 // execution of JS code. However, as calling StackTracer requires 332 // execution of JS code. However, as calling StackTracer requires
347 // entering native code, we can only emulate pure JS by erasing 333 // entering native code, we can only emulate pure JS by erasing
348 // Top::c_entry_fp value. In this case, StackTracer uses passed frame 334 // Top::c_entry_fp value. In this case, StackTracer uses passed frame
349 // pointer value as a starting point for stack walking. 335 // pointer value as a starting point for stack walking.
350 TEST(PureJSStackTrace) { 336 TEST(PureJSStackTrace) {
351 TickSample sample; 337 TickSample sample;
(...skipping 11 matching lines...) Expand all
363 "function OuterJSTrace() {" 349 "function OuterJSTrace() {"
364 " JSTrace();" 350 " JSTrace();"
365 "};\n" 351 "};\n"
366 "OuterJSTrace();\n" 352 "OuterJSTrace();\n"
367 "true;"); 353 "true;");
368 CHECK(!result.IsEmpty()); 354 CHECK(!result.IsEmpty());
369 // When stack tracer is invoked, the stack should look as follows: 355 // When stack tracer is invoked, the stack should look as follows:
370 // script [JS] 356 // script [JS]
371 // OuterJSTrace() [JS] 357 // OuterJSTrace() [JS]
372 // JSTrace() [JS] 358 // JSTrace() [JS]
373 // JSFuncDoTrace() [JS] [captures EBP value and encodes it as Smi] 359 // JSFuncDoTrace() [JS]
374 // js_trace(EBP encoded as Smi) [native (extension)] 360 // js_trace(EBP) [native (extension)]
375 // DoTraceHideCEntryFPAddress(EBP) [native] 361 // DoTraceHideCEntryFPAddress(EBP) [native]
376 // StackTracer::Trace 362 // StackTracer::Trace
377 // 363 //
378 // The last JS function called. It is only visible through 364 // The last JS function called. It is only visible through
379 // sample.function, as its return address is above captured EBP value. 365 // sample.function, as its return address is above captured EBP value.
380 CHECK_EQ(GetGlobalJSFunction("JSFuncDoTrace")->address(), 366 CheckJSFunctionAtAddress("JSFuncDoTrace", sample.function);
381 sample.function);
382 CHECK_GT(sample.frames_count, 1); 367 CHECK_GT(sample.frames_count, 1);
383 // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace" 368 // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
384 CheckObjectIsJSFunction("JSTrace", sample.stack[0]); 369 CheckJSFunctionAtAddress("JSTrace", sample.stack[0]);
385 CheckObjectIsJSFunction("OuterJSTrace", sample.stack[1]); 370 CheckJSFunctionAtAddress("OuterJSTrace", sample.stack[1]);
386 } 371 }
387 372
388 373
389 static void CFuncDoTrace(byte dummy_parameter) { 374 static void CFuncDoTrace(byte dummy_parameter) {
390 Address fp; 375 Address fp;
391 #ifdef __GNUC__ 376 #ifdef __GNUC__
392 fp = reinterpret_cast<Address>(__builtin_frame_address(0)); 377 fp = reinterpret_cast<Address>(__builtin_frame_address(0));
393 #elif defined _MSC_VER 378 #elif defined _MSC_VER
394 // Approximate a frame pointer address. We compile without base pointers, 379 // Approximate a frame pointer address. We compile without base pointers,
395 // so we can't trust ebp/rbp. 380 // so we can't trust ebp/rbp.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 CHECK_EQ(0, GetJsEntrySp()); 413 CHECK_EQ(0, GetJsEntrySp());
429 CompileRun("a = 1; b = a + 1;"); 414 CompileRun("a = 1; b = a + 1;");
430 CHECK_EQ(0, GetJsEntrySp()); 415 CHECK_EQ(0, GetJsEntrySp());
431 CompileRun("js_entry_sp();"); 416 CompileRun("js_entry_sp();");
432 CHECK_EQ(0, GetJsEntrySp()); 417 CHECK_EQ(0, GetJsEntrySp());
433 CompileRun("js_entry_sp_level2();"); 418 CompileRun("js_entry_sp_level2();");
434 CHECK_EQ(0, GetJsEntrySp()); 419 CHECK_EQ(0, GetJsEntrySp());
435 } 420 }
436 421
437 #endif // ENABLE_LOGGING_AND_PROFILING 422 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/x64/frames-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698