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

Side by Side Diff: runtime/vm/object.cc

Issue 2646443005: Track async causal stack traces (Closed)
Patch Set: rebase Created 3 years, 10 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 | « runtime/vm/object.h ('k') | runtime/vm/object_service.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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/become.h" 10 #include "vm/become.h"
(...skipping 22276 matching lines...) Expand 10 before | Expand all | Expand 10 after
22287 } 22287 }
22288 22288
22289 22289
22290 void StackTrace::SetPcOffsetAtFrame(intptr_t frame_index, 22290 void StackTrace::SetPcOffsetAtFrame(intptr_t frame_index,
22291 const Smi& pc_offset) const { 22291 const Smi& pc_offset) const {
22292 const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_); 22292 const Array& pc_offset_array = Array::Handle(raw_ptr()->pc_offset_array_);
22293 pc_offset_array.SetAt(frame_index, pc_offset); 22293 pc_offset_array.SetAt(frame_index, pc_offset);
22294 } 22294 }
22295 22295
22296 22296
22297 void StackTrace::set_async_link(const StackTrace& async_link) const {
22298 StorePointer(&raw_ptr()->async_link_, async_link.raw());
22299 }
22300
22301
22297 void StackTrace::set_code_array(const Array& code_array) const { 22302 void StackTrace::set_code_array(const Array& code_array) const {
22298 StorePointer(&raw_ptr()->code_array_, code_array.raw()); 22303 StorePointer(&raw_ptr()->code_array_, code_array.raw());
22299 } 22304 }
22300 22305
22301 22306
22302 void StackTrace::set_pc_offset_array(const Array& pc_offset_array) const { 22307 void StackTrace::set_pc_offset_array(const Array& pc_offset_array) const {
22303 StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw()); 22308 StorePointer(&raw_ptr()->pc_offset_array_, pc_offset_array.raw());
22304 } 22309 }
22305 22310
22306 22311
(...skipping 17 matching lines...) Expand all
22324 NoSafepointScope no_safepoint; 22329 NoSafepointScope no_safepoint;
22325 result ^= raw; 22330 result ^= raw;
22326 } 22331 }
22327 result.set_code_array(code_array); 22332 result.set_code_array(code_array);
22328 result.set_pc_offset_array(pc_offset_array); 22333 result.set_pc_offset_array(pc_offset_array);
22329 result.set_expand_inlined(true); // default. 22334 result.set_expand_inlined(true); // default.
22330 return result.raw(); 22335 return result.raw();
22331 } 22336 }
22332 22337
22333 22338
22339 RawStackTrace* StackTrace::New(const Array& code_array,
22340 const Array& pc_offset_array,
22341 const StackTrace& async_link,
22342 Heap::Space space) {
22343 StackTrace& result = StackTrace::Handle();
22344 {
22345 RawObject* raw = Object::Allocate(StackTrace::kClassId,
22346 StackTrace::InstanceSize(), space);
22347 NoSafepointScope no_safepoint;
22348 result ^= raw;
22349 }
22350 result.set_async_link(async_link);
22351 result.set_code_array(code_array);
22352 result.set_pc_offset_array(pc_offset_array);
22353 result.set_expand_inlined(true); // default.
22354 return result.raw();
22355 }
22356
22357
22334 const char* StackTrace::ToCString() const { 22358 const char* StackTrace::ToCString() const {
22335 intptr_t idx = 0; 22359 intptr_t idx = 0;
22336 return ToCStringInternal(&idx); 22360 return ToCStringInternal(*this, &idx);
22337 } 22361 }
22338 22362
22339 22363
22340 static intptr_t PrintOneStackTrace(Zone* zone, 22364 static intptr_t PrintOneStackTrace(Zone* zone,
22341 GrowableArray<char*>* frame_strings, 22365 GrowableArray<char*>* frame_strings,
22342 uword pc, 22366 uword pc,
22343 const Function& function, 22367 const Function& function,
22344 const Code& code, 22368 const Code& code,
22345 intptr_t frame_index) { 22369 intptr_t frame_index) {
22346 const TokenPosition token_pos = code.GetTokenIndexOfPC(pc); 22370 const TokenPosition token_pos = code.GetTokenIndexOfPC(pc);
(...skipping 21 matching lines...) Expand all
22368 function_name.ToCString(), url.ToCString(), line); 22392 function_name.ToCString(), url.ToCString(), line);
22369 } else { 22393 } else {
22370 chars = OS::SCreate(zone, "#%-6" Pd " %s (%s)\n", frame_index, 22394 chars = OS::SCreate(zone, "#%-6" Pd " %s (%s)\n", frame_index,
22371 function_name.ToCString(), url.ToCString()); 22395 function_name.ToCString(), url.ToCString());
22372 } 22396 }
22373 frame_strings->Add(chars); 22397 frame_strings->Add(chars);
22374 return strlen(chars); 22398 return strlen(chars);
22375 } 22399 }
22376 22400
22377 22401
22378 const char* StackTrace::ToCStringInternal(intptr_t* frame_index, 22402 const char* StackTrace::ToCStringInternal(const StackTrace& stack_trace_in,
22379 intptr_t max_frames) const { 22403 intptr_t* frame_index,
22404 intptr_t max_frames) {
22380 Zone* zone = Thread::Current()->zone(); 22405 Zone* zone = Thread::Current()->zone();
22381 Function& function = Function::Handle(); 22406 Function& function = Function::Handle(zone);
22382 Code& code = Code::Handle(); 22407 Code& code = Code::Handle(zone);
22383 // Iterate through the stack frames and create C string description 22408 // Iterate through the stack frames and create C string description
22384 // for each frame. 22409 // for each frame.
22385 intptr_t total_len = 0; 22410 intptr_t total_len = 0;
22386 GrowableArray<char*> frame_strings; 22411 GrowableArray<char*> frame_strings;
22387 for (intptr_t i = 0; (i < Length()) && (*frame_index < max_frames); i++) { 22412 StackTrace& stack_trace = StackTrace::Handle(zone);
22388 function = FunctionAtFrame(i); 22413 stack_trace ^= stack_trace_in.raw();
22389 if (function.IsNull()) { 22414 while (!stack_trace.IsNull()) {
22390 // Check for a null function, which indicates a gap in a StackOverflow or 22415 for (intptr_t i = 0;
22391 // OutOfMemory trace. 22416 (i < stack_trace.Length()) && (*frame_index < max_frames); i++) {
22392 if ((i < (Length() - 1)) && 22417 code = stack_trace.CodeAtFrame(i);
22393 (FunctionAtFrame(i + 1) != Function::null())) { 22418 function = stack_trace.FunctionAtFrame(i);
22394 const char* kTruncated = "...\n...\n"; 22419 if (code.raw() == StubCode::AsynchronousGapMarker_entry()->code()) {
22395 intptr_t truncated_len = strlen(kTruncated) + 1; 22420 const char* kAsyncSuspension = "<asynchronous suspension>\n";
22396 char* chars = zone->Alloc<char>(truncated_len); 22421 intptr_t async_suspension_len = strlen(kAsyncSuspension) + 1;
22397 OS::SNPrint(chars, truncated_len, "%s", kTruncated); 22422 char* chars = zone->Alloc<char>(async_suspension_len);
22423 OS::SNPrint(chars, async_suspension_len, "%s", kAsyncSuspension);
22398 frame_strings.Add(chars); 22424 frame_strings.Add(chars);
22399 total_len += truncated_len; 22425 total_len += async_suspension_len;
22400 ASSERT(PcOffsetAtFrame(i) != Smi::null()); 22426 } else if (function.IsNull()) {
22401 // To account for gap frames. 22427 // Check for a null function, which indicates a gap in a StackOverflow
22402 (*frame_index) += Smi::Value(PcOffsetAtFrame(i)); 22428 // or OutOfMemory trace.
22403 } 22429 if ((i < (stack_trace.Length() - 1)) &&
22404 } else { 22430 (stack_trace.FunctionAtFrame(i + 1) != Function::null())) {
22405 code = CodeAtFrame(i); 22431 const char* kTruncated = "...\n...\n";
22406 ASSERT(function.raw() == code.function()); 22432 intptr_t truncated_len = strlen(kTruncated) + 1;
22407 uword pc = code.PayloadStart() + Smi::Value(PcOffsetAtFrame(i)); 22433 char* chars = zone->Alloc<char>(truncated_len);
22408 if (code.is_optimized() && expand_inlined() && 22434 OS::SNPrint(chars, truncated_len, "%s", kTruncated);
22409 !FLAG_precompiled_runtime) { 22435 frame_strings.Add(chars);
22410 // Traverse inlined frames. 22436 total_len += truncated_len;
22411 for (InlinedFunctionsIterator it(code, pc); 22437 ASSERT(stack_trace.PcOffsetAtFrame(i) != Smi::null());
22412 !it.Done() && (*frame_index < max_frames); it.Advance()) { 22438 // To account for gap frames.
22413 function = it.function(); 22439 (*frame_index) += Smi::Value(stack_trace.PcOffsetAtFrame(i));
22440 }
22441 } else {
22442 code = stack_trace.CodeAtFrame(i);
22443 ASSERT(function.raw() == code.function());
22444 uword pc =
22445 code.PayloadStart() + Smi::Value(stack_trace.PcOffsetAtFrame(i));
22446 if (code.is_optimized() && stack_trace.expand_inlined() &&
22447 !FLAG_precompiled_runtime) {
22448 // Traverse inlined frames.
22449 for (InlinedFunctionsIterator it(code, pc);
22450 !it.Done() && (*frame_index < max_frames); it.Advance()) {
22451 function = it.function();
22452 if (function.is_visible() || FLAG_show_invisible_frames) {
22453 code = it.code();
22454 ASSERT(function.raw() == code.function());
22455 uword pc = it.pc();
22456 ASSERT(pc != 0);
22457 ASSERT(code.PayloadStart() <= pc);
22458 ASSERT(pc < (code.PayloadStart() + code.Size()));
22459 total_len += PrintOneStackTrace(zone, &frame_strings, pc,
22460 function, code, *frame_index);
22461 (*frame_index)++; // To account for inlined frames.
22462 }
22463 }
22464 } else {
22414 if (function.is_visible() || FLAG_show_invisible_frames) { 22465 if (function.is_visible() || FLAG_show_invisible_frames) {
22415 code = it.code();
22416 ASSERT(function.raw() == code.function());
22417 uword pc = it.pc();
22418 ASSERT(pc != 0);
22419 ASSERT(code.PayloadStart() <= pc);
22420 ASSERT(pc < (code.PayloadStart() + code.Size()));
22421 total_len += PrintOneStackTrace(zone, &frame_strings, pc, function, 22466 total_len += PrintOneStackTrace(zone, &frame_strings, pc, function,
22422 code, *frame_index); 22467 code, *frame_index);
22423 (*frame_index)++; // To account for inlined frames. 22468 (*frame_index)++;
22424 } 22469 }
22425 } 22470 }
22426 } else {
22427 if (function.is_visible() || FLAG_show_invisible_frames) {
22428 total_len += PrintOneStackTrace(zone, &frame_strings, pc, function,
22429 code, *frame_index);
22430 (*frame_index)++;
22431 }
22432 } 22471 }
22433 } 22472 }
22473 // Follow the link.
22474 stack_trace ^= stack_trace.async_link();
22434 } 22475 }
22435 22476
22436 // Now concatenate the frame descriptions into a single C string. 22477 // Now concatenate the frame descriptions into a single C string.
22437 char* chars = zone->Alloc<char>(total_len + 1); 22478 char* chars = zone->Alloc<char>(total_len + 1);
22438 intptr_t index = 0; 22479 intptr_t index = 0;
22439 for (intptr_t i = 0; i < frame_strings.length(); i++) { 22480 for (intptr_t i = 0; i < frame_strings.length(); i++) {
22440 index += OS::SNPrint((chars + index), (total_len + 1 - index), "%s", 22481 index += OS::SNPrint((chars + index), (total_len + 1 - index), "%s",
22441 frame_strings[i]); 22482 frame_strings[i]);
22442 } 22483 }
22443 chars[total_len] = '\0'; 22484 chars[total_len] = '\0';
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
22759 return UserTag::null(); 22800 return UserTag::null();
22760 } 22801 }
22761 22802
22762 22803
22763 const char* UserTag::ToCString() const { 22804 const char* UserTag::ToCString() const {
22764 const String& tag_label = String::Handle(label()); 22805 const String& tag_label = String::Handle(label());
22765 return tag_label.ToCString(); 22806 return tag_label.ToCString();
22766 } 22807 }
22767 22808
22768 } // namespace dart 22809 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698