| OLD | NEW |
| 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/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 21582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21593 } else { | 21593 } else { |
| 21594 chars = OS::SCreate(zone, | 21594 chars = OS::SCreate(zone, |
| 21595 "#%-6" Pd " %s (%s)\n", | 21595 "#%-6" Pd " %s (%s)\n", |
| 21596 frame_index, function_name.ToCString(), url.ToCString()); | 21596 frame_index, function_name.ToCString(), url.ToCString()); |
| 21597 } | 21597 } |
| 21598 frame_strings->Add(chars); | 21598 frame_strings->Add(chars); |
| 21599 return strlen(chars); | 21599 return strlen(chars); |
| 21600 } | 21600 } |
| 21601 | 21601 |
| 21602 | 21602 |
| 21603 static intptr_t PrintOneStacktraceNoCode(Zone* zone, |
| 21604 GrowableArray<char*>* frame_strings, |
| 21605 const Function& function, |
| 21606 intptr_t frame_index) { |
| 21607 const Script& script = Script::Handle(zone, function.script()); |
| 21608 const String& function_name = |
| 21609 String::Handle(zone, function.QualifiedUserVisibleName()); |
| 21610 const String& url = String::Handle(zone, script.url()); |
| 21611 char* chars = NULL; |
| 21612 chars = OS::SCreate(zone, |
| 21613 "#%-6" Pd " %s (%s)\n", |
| 21614 frame_index, function_name.ToCString(), url.ToCString()); |
| 21615 frame_strings->Add(chars); |
| 21616 return strlen(chars); |
| 21617 } |
| 21618 |
| 21619 |
| 21603 const char* Stacktrace::ToCStringInternal(intptr_t* frame_index, | 21620 const char* Stacktrace::ToCStringInternal(intptr_t* frame_index, |
| 21604 intptr_t max_frames) const { | 21621 intptr_t max_frames) const { |
| 21605 Zone* zone = Thread::Current()->zone(); | 21622 Zone* zone = Thread::Current()->zone(); |
| 21606 Function& function = Function::Handle(); | 21623 Function& function = Function::Handle(); |
| 21607 Code& code = Code::Handle(); | 21624 Code& code = Code::Handle(); |
| 21608 // Iterate through the stack frames and create C string description | 21625 // Iterate through the stack frames and create C string description |
| 21609 // for each frame. | 21626 // for each frame. |
| 21610 intptr_t total_len = 0; | 21627 intptr_t total_len = 0; |
| 21611 GrowableArray<char*> frame_strings; | 21628 GrowableArray<char*> frame_strings; |
| 21612 for (intptr_t i = 0; (i < Length()) && (*frame_index < max_frames); i++) { | 21629 for (intptr_t i = 0; (i < Length()) && (*frame_index < max_frames); i++) { |
| 21613 function = FunctionAtFrame(i); | 21630 function = FunctionAtFrame(i); |
| 21614 if (function.IsNull()) { | 21631 if (function.IsNull()) { |
| 21615 // Check if null function object indicates a stack trace overflow. | 21632 // Check if null function object indicates a gap in a StackOverflow or |
| 21633 // OutOfMemory trace. |
| 21616 if ((i < (Length() - 1)) && | 21634 if ((i < (Length() - 1)) && |
| 21617 (FunctionAtFrame(i + 1) != Function::null())) { | 21635 (FunctionAtFrame(i + 1) != Function::null())) { |
| 21618 const char* kTruncated = "...\n...\n"; | 21636 const char* kTruncated = "...\n...\n"; |
| 21619 intptr_t truncated_len = strlen(kTruncated) + 1; | 21637 intptr_t truncated_len = strlen(kTruncated) + 1; |
| 21620 char* chars = zone->Alloc<char>(truncated_len); | 21638 char* chars = zone->Alloc<char>(truncated_len); |
| 21621 OS::SNPrint(chars, truncated_len, "%s", kTruncated); | 21639 OS::SNPrint(chars, truncated_len, "%s", kTruncated); |
| 21622 frame_strings.Add(chars); | 21640 frame_strings.Add(chars); |
| 21623 total_len += truncated_len; | 21641 total_len += truncated_len; |
| 21624 } | 21642 } |
| 21625 } else if (function.is_visible() || FLAG_show_invisible_frames) { | 21643 } else { |
| 21626 code = CodeAtFrame(i); | 21644 code = CodeAtFrame(i); |
| 21627 ASSERT(function.raw() == code.function()); | 21645 ASSERT(function.raw() == code.function()); |
| 21628 uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i)); | 21646 uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i)); |
| 21629 if (code.is_optimized() && expand_inlined()) { | 21647 if (code.is_optimized() && expand_inlined()) { |
| 21630 // Traverse inlined frames. | 21648 // Traverse inlined frames. |
| 21631 for (InlinedFunctionsIterator it(code, pc); | 21649 if (Compiler::allow_recompilation()) { |
| 21632 !it.Done() && (*frame_index < max_frames); it.Advance()) { | 21650 for (InlinedFunctionsIterator it(code, pc); |
| 21633 function = it.function(); | 21651 !it.Done() && (*frame_index < max_frames); it.Advance()) { |
| 21634 if (function.is_visible() || FLAG_show_invisible_frames) { | 21652 function = it.function(); |
| 21635 code = it.code(); | 21653 if (function.is_visible() || FLAG_show_invisible_frames) { |
| 21636 ASSERT(function.raw() == code.function()); | 21654 code = it.code(); |
| 21637 uword pc = it.pc(); | 21655 ASSERT(function.raw() == code.function()); |
| 21638 ASSERT(pc != 0); | 21656 uword pc = it.pc(); |
| 21639 ASSERT(code.EntryPoint() <= pc); | 21657 ASSERT(pc != 0); |
| 21640 ASSERT(pc < (code.EntryPoint() + code.Size())); | 21658 ASSERT(code.EntryPoint() <= pc); |
| 21641 total_len += PrintOneStacktrace( | 21659 ASSERT(pc < (code.EntryPoint() + code.Size())); |
| 21642 zone, &frame_strings, pc, function, code, *frame_index); | 21660 total_len += PrintOneStacktrace( |
| 21643 (*frame_index)++; // To account for inlined frames. | 21661 zone, &frame_strings, pc, function, code, *frame_index); |
| 21662 (*frame_index)++; // To account for inlined frames. |
| 21663 } |
| 21664 } |
| 21665 } else { |
| 21666 // Precompilation: we don't have deopt info, so we don't know the |
| 21667 // source position of inlined functions, but we can still name them. |
| 21668 intptr_t offset = Smi::Value(PcOffsetAtFrame(i)); |
| 21669 // The PC of frames below the top frame is a call's return address, |
| 21670 // which can belong to a different inlining interval than the call. |
| 21671 intptr_t effective_offset = offset - 1; |
| 21672 GrowableArray<Function*> inlined_functions; |
| 21673 code.GetInlinedFunctionsAt(effective_offset, &inlined_functions); |
| 21674 ASSERT(inlined_functions.length() >= 1); // At least the inliner. |
| 21675 for (intptr_t j = 0; j < inlined_functions.length(); j++) { |
| 21676 Function* inlined_function = inlined_functions[j]; |
| 21677 ASSERT(inlined_function != NULL); |
| 21678 ASSERT(!inlined_function->IsNull()); |
| 21679 if (inlined_function->is_visible() || FLAG_show_invisible_frames) { |
| 21680 total_len += PrintOneStacktraceNoCode( |
| 21681 zone, &frame_strings, *inlined_function, *frame_index); |
| 21682 (*frame_index)++; |
| 21683 } |
| 21644 } | 21684 } |
| 21645 } | 21685 } |
| 21646 } else { | 21686 } else { |
| 21647 total_len += PrintOneStacktrace( | 21687 if (function.is_visible() || FLAG_show_invisible_frames) { |
| 21648 zone, &frame_strings, pc, function, code, *frame_index); | 21688 total_len += PrintOneStacktrace( |
| 21649 (*frame_index)++; | 21689 zone, &frame_strings, pc, function, code, *frame_index); |
| 21690 (*frame_index)++; |
| 21691 } |
| 21650 } | 21692 } |
| 21651 } | 21693 } |
| 21652 } | 21694 } |
| 21653 | 21695 |
| 21654 // Now concatenate the frame descriptions into a single C string. | 21696 // Now concatenate the frame descriptions into a single C string. |
| 21655 char* chars = zone->Alloc<char>(total_len + 1); | 21697 char* chars = zone->Alloc<char>(total_len + 1); |
| 21656 intptr_t index = 0; | 21698 intptr_t index = 0; |
| 21657 for (intptr_t i = 0; i < frame_strings.length(); i++) { | 21699 for (intptr_t i = 0; i < frame_strings.length(); i++) { |
| 21658 index += OS::SNPrint((chars + index), | 21700 index += OS::SNPrint((chars + index), |
| 21659 (total_len + 1 - index), | 21701 (total_len + 1 - index), |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 22033 return tag_label.ToCString(); | 22075 return tag_label.ToCString(); |
| 22034 } | 22076 } |
| 22035 | 22077 |
| 22036 | 22078 |
| 22037 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { | 22079 void UserTag::PrintJSONImpl(JSONStream* stream, bool ref) const { |
| 22038 Instance::PrintJSONImpl(stream, ref); | 22080 Instance::PrintJSONImpl(stream, ref); |
| 22039 } | 22081 } |
| 22040 | 22082 |
| 22041 | 22083 |
| 22042 } // namespace dart | 22084 } // namespace dart |
| OLD | NEW |