From ea6221d4e6932619caf429780f886c70ca3a81ca Mon Sep 17 00:00:00 2001 From: "mikhail.naganov@gmail.com" Date: Wed, 24 Mar 2010 08:46:17 +0000 Subject: [PATCH] Add comments to test-log-stack-tracer. Review URL: http://codereview.chromium.org/1181001 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4240 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- test/cctest/test-log-stack-tracer.cc | 37 ++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/test/cctest/test-log-stack-tracer.cc b/test/cctest/test-log-stack-tracer.cc index d96e5e7..532311b 100644 --- a/test/cctest/test-log-stack-tracer.cc +++ b/test/cctest/test-log-stack-tracer.cc @@ -284,12 +284,18 @@ static void CreateTraceCallerFunction(const char* func_name, } +// This test verifies that stack tracing works when called during +// execution of a native function called from JS code. In this case, +// StackTracer uses Top::c_entry_fp as a starting point for stack +// walking. TEST(CFromJSStackTrace) { TickSample sample; InitTraceEnv(&sample); InitializeVM(); v8::HandleScope scope; + // Create global function JSFuncDoTrace which calls + // extension function trace() with the current frame pointer value. CreateTraceCallerFunction("JSFuncDoTrace", "trace"); Local result = CompileRun( "function JSTrace() {" @@ -298,8 +304,15 @@ TEST(CFromJSStackTrace) { "JSTrace();\n" "true;"); CHECK(!result.IsEmpty()); + // When stack tracer is invoked, the stack should look as follows: + // script [JS] + // JSTrace() [JS] + // JSFuncDoTrace() [JS] [captures EBP value and encodes it as Smi] + // trace(EBP encoded as Smi) [native (extension)] + // DoTrace(EBP) [native] + // StackTracer::Trace CHECK_GT(sample.frames_count, 1); - // Stack sampling will start from the first JS function, i.e. "JSFuncDoTrace" + // Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace" CheckRetAddrIsInJSFunction("JSFuncDoTrace", sample.stack[0]); CheckRetAddrIsInJSFunction("JSTrace", @@ -307,12 +320,19 @@ TEST(CFromJSStackTrace) { } +// This test verifies that stack tracing works when called during +// execution of JS code. However, as calling StackTracer requires +// entering native code, we can only emulate pure JS by erasing +// Top::c_entry_fp value. In this case, StackTracer uses passed frame +// pointer value as a starting point for stack walking. TEST(PureJSStackTrace) { TickSample sample; InitTraceEnv(&sample); InitializeVM(); v8::HandleScope scope; + // Create global function JSFuncDoTrace which calls + // extension function js_trace() with the current frame pointer value. CreateTraceCallerFunction("JSFuncDoTrace", "js_trace"); Local result = CompileRun( "function JSTrace() {" @@ -324,7 +344,17 @@ TEST(PureJSStackTrace) { "OuterJSTrace();\n" "true;"); CHECK(!result.IsEmpty()); - // The last JS function called. + // When stack tracer is invoked, the stack should look as follows: + // script [JS] + // OuterJSTrace() [JS] + // JSTrace() [JS] + // JSFuncDoTrace() [JS] [captures EBP value and encodes it as Smi] + // js_trace(EBP encoded as Smi) [native (extension)] + // DoTraceHideCEntryFPAddress(EBP) [native] + // StackTracer::Trace + // + // The last JS function called. It is only visible through + // sample.function, as its return address is above captured EBP value. CHECK_EQ(GetGlobalJSFunction("JSFuncDoTrace")->address(), sample.function); CHECK_GT(sample.frames_count, 1); @@ -361,6 +391,9 @@ static int CFunc(int depth) { } +// This test verifies that stack tracing doesn't crash when called on +// pure native code. StackTracer only unrolls JS code, so we can't +// get any meaningful info here. TEST(PureCStackTrace) { TickSample sample; InitTraceEnv(&sample); -- 2.7.4