Chromium Code Reviews| 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/become.h" | 10 #include "vm/become.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 #include "vm/deopt_instructions.h" | 23 #include "vm/deopt_instructions.h" |
| 24 #include "vm/disassembler.h" | 24 #include "vm/disassembler.h" |
| 25 #include "vm/double_conversion.h" | 25 #include "vm/double_conversion.h" |
| 26 #include "vm/exceptions.h" | 26 #include "vm/exceptions.h" |
| 27 #include "vm/growable_array.h" | 27 #include "vm/growable_array.h" |
| 28 #include "vm/hash_table.h" | 28 #include "vm/hash_table.h" |
| 29 #include "vm/heap.h" | 29 #include "vm/heap.h" |
| 30 #include "vm/intrinsifier.h" | 30 #include "vm/intrinsifier.h" |
| 31 #include "vm/isolate_reload.h" | 31 #include "vm/isolate_reload.h" |
| 32 #include "vm/kernel_to_il.h" | 32 #include "vm/kernel_to_il.h" |
| 33 #include "vm/native_symbol.h" | |
| 33 #include "vm/object_store.h" | 34 #include "vm/object_store.h" |
| 34 #include "vm/parser.h" | 35 #include "vm/parser.h" |
| 35 #include "vm/precompiler.h" | 36 #include "vm/precompiler.h" |
| 36 #include "vm/profiler.h" | 37 #include "vm/profiler.h" |
| 37 #include "vm/resolver.h" | 38 #include "vm/resolver.h" |
| 38 #include "vm/reusable_handles.h" | 39 #include "vm/reusable_handles.h" |
| 39 #include "vm/runtime_entry.h" | 40 #include "vm/runtime_entry.h" |
| 40 #include "vm/scopes.h" | 41 #include "vm/scopes.h" |
| 41 #include "vm/stack_frame.h" | 42 #include "vm/stack_frame.h" |
| 42 #include "vm/symbols.h" | 43 #include "vm/symbols.h" |
| (...skipping 9110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9153 token_pos = Smi::New(tkit.CurrentPosition().value() + 1); | 9154 token_pos = Smi::New(tkit.CurrentPosition().value() + 1); |
| 9154 line_starts_list.Add(token_pos); | 9155 line_starts_list.Add(token_pos); |
| 9155 } | 9156 } |
| 9156 tkit.Advance(); | 9157 tkit.Advance(); |
| 9157 } | 9158 } |
| 9158 line_starts_array = Array::MakeArray(line_starts_list); | 9159 line_starts_array = Array::MakeArray(line_starts_list); |
| 9159 set_line_starts(line_starts_array); | 9160 set_line_starts(line_starts_array); |
| 9160 } | 9161 } |
| 9161 | 9162 |
| 9162 ASSERT(line_starts_array.Length() > 0); | 9163 ASSERT(line_starts_array.Length() > 0); |
| 9163 intptr_t offset = target_token_pos.value(); | 9164 intptr_t offset = target_token_pos.Pos(); |
| 9164 intptr_t min = 0; | 9165 intptr_t min = 0; |
| 9165 intptr_t max = line_starts_array.Length() - 1; | 9166 intptr_t max = line_starts_array.Length() - 1; |
| 9166 | 9167 |
| 9167 // Binary search to find the line containing this offset. | 9168 // Binary search to find the line containing this offset. |
| 9168 while (min < max) { | 9169 while (min < max) { |
| 9169 int midpoint = (max - min + 1) / 2 + min; | 9170 int midpoint = (max - min + 1) / 2 + min; |
| 9170 token_pos ^= line_starts_array.At(midpoint); | 9171 token_pos ^= line_starts_array.At(midpoint); |
| 9171 if (token_pos.Value() > offset) { | 9172 if (token_pos.Value() > offset) { |
| 9172 max = midpoint - 1; | 9173 max = midpoint - 1; |
| 9173 } else { | 9174 } else { |
| (...skipping 13370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 22544 } | 22545 } |
| 22545 | 22546 |
| 22546 | 22547 |
| 22547 const char* StackTrace::ToCStringInternal(const StackTrace& stack_trace_in, | 22548 const char* StackTrace::ToCStringInternal(const StackTrace& stack_trace_in, |
| 22548 intptr_t* frame_index, | 22549 intptr_t* frame_index, |
| 22549 intptr_t max_frames) { | 22550 intptr_t max_frames) { |
| 22550 Zone* zone = Thread::Current()->zone(); | 22551 Zone* zone = Thread::Current()->zone(); |
| 22551 StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw()); | 22552 StackTrace& stack_trace = StackTrace::Handle(zone, stack_trace_in.raw()); |
| 22552 Function& function = Function::Handle(zone); | 22553 Function& function = Function::Handle(zone); |
| 22553 Code& code = Code::Handle(zone); | 22554 Code& code = Code::Handle(zone); |
| 22555 | |
| 22554 GrowableArray<const Function*> inlined_functions; | 22556 GrowableArray<const Function*> inlined_functions; |
| 22555 GrowableArray<TokenPosition> inlined_token_positions; | 22557 GrowableArray<TokenPosition> inlined_token_positions; |
| 22556 ZoneTextBuffer buffer(zone, 1024); | 22558 ZoneTextBuffer buffer(zone, 1024); |
| 22557 | 22559 |
| 22560 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) | |
| 22561 if (FLAG_dwarf_stack_traces) { | |
| 22562 // This prologue imitates Android's debuggerd to make it possible to paste | |
| 22563 // the stack trace into ndk-stack. | |
| 22564 buffer.Printf( | |
| 22565 "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"); | |
| 22566 OSThread* thread = OSThread::Current(); | |
| 22567 buffer.Printf("pid: %" Pd ", tid: %" Pd ", name %s\n", OS::ProcessId(), | |
| 22568 OSThread::ThreadIdToIntPtr(thread->id()), thread->name()); | |
| 22569 } | |
| 22570 #endif | |
| 22571 | |
| 22558 // Iterate through the stack frames and create C string description | 22572 // Iterate through the stack frames and create C string description |
| 22559 // for each frame. | 22573 // for each frame. |
| 22560 do { | 22574 do { |
| 22561 for (intptr_t i = 0; | 22575 for (intptr_t i = 0; |
| 22562 (i < stack_trace.Length()) && (*frame_index < max_frames); i++) { | 22576 (i < stack_trace.Length()) && (*frame_index < max_frames); i++) { |
| 22563 code = stack_trace.CodeAtFrame(i); | 22577 code = stack_trace.CodeAtFrame(i); |
| 22564 if (code.IsNull()) { | 22578 if (code.IsNull()) { |
| 22565 // Check for a null function, which indicates a gap in a StackOverflow | 22579 // Check for a null function, which indicates a gap in a StackOverflow |
| 22566 // or OutOfMemory trace. | 22580 // or OutOfMemory trace. |
| 22567 if ((i < (stack_trace.Length() - 1)) && | 22581 if ((i < (stack_trace.Length() - 1)) && |
| 22568 (stack_trace.CodeAtFrame(i + 1) != Code::null())) { | 22582 (stack_trace.CodeAtFrame(i + 1) != Code::null())) { |
| 22569 buffer.AddString("...\n...\n"); | 22583 buffer.AddString("...\n...\n"); |
| 22570 ASSERT(stack_trace.PcOffsetAtFrame(i) != Smi::null()); | 22584 ASSERT(stack_trace.PcOffsetAtFrame(i) != Smi::null()); |
| 22571 // To account for gap frames. | 22585 // To account for gap frames. |
| 22572 (*frame_index) += Smi::Value(stack_trace.PcOffsetAtFrame(i)); | 22586 (*frame_index) += Smi::Value(stack_trace.PcOffsetAtFrame(i)); |
| 22573 } | 22587 } |
| 22574 } else if (code.raw() == | 22588 } else if (code.raw() == |
| 22575 StubCode::AsynchronousGapMarker_entry()->code()) { | 22589 StubCode::AsynchronousGapMarker_entry()->code()) { |
| 22576 buffer.AddString("<asynchronous suspension>\n"); | 22590 buffer.AddString("<asynchronous suspension>\n"); |
| 22577 // The frame immediately after the asynchronous gap marker is the | 22591 // The frame immediately after the asynchronous gap marker is the |
| 22578 // identical to the frame above the marker. Skip the frame to enhance | 22592 // identical to the frame above the marker. Skip the frame to enhance |
| 22579 // the readability of the trace. | 22593 // the readability of the trace. |
| 22580 i++; | 22594 i++; |
| 22581 } else { | 22595 } else { |
| 22582 ASSERT(code.IsFunctionCode()); | 22596 ASSERT(code.IsFunctionCode()); |
| 22583 intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i)); | 22597 intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i)); |
| 22598 | |
| 22599 #if defined(DART_PRECOMPILER) || defined(DART_PRECOMPILED_RUNTIME) | |
| 22600 if (FLAG_dwarf_stack_traces) { | |
| 22601 // This output is formatted like Android's debuggerd. Note debuggerd | |
| 22602 // prints call addresses instead of return addresses. | |
| 22603 uword return_addr = code.PayloadStart() + pc_offset; | |
| 22604 uword call_addr = return_addr - 1; | |
|
Cutch
2017/03/15 14:54:13
This function is getting too complex. Refactor thi
rmacnak
2017/03/16 17:50:11
Split into Dart and Android print functions. Also
| |
| 22605 uword dso_base; | |
| 22606 char* dso_name; | |
| 22607 if (NativeSymbolResolver::LookupSharedObject(call_addr, &dso_base, | |
| 22608 &dso_name)) { | |
| 22609 uword dso_offset = call_addr - dso_base; | |
| 22610 buffer.Printf(" #%02" Pd " pc %" Pp " %s\n", *frame_index, | |
| 22611 dso_offset, dso_name); | |
| 22612 NativeSymbolResolver::FreeSymbolName(dso_name); | |
| 22613 } else { | |
| 22614 buffer.Printf(" #%02" Pd " pc %" Pp " <unknown>\n", | |
| 22615 *frame_index, call_addr); | |
| 22616 } | |
| 22617 (*frame_index)++; | |
| 22618 continue; | |
| 22619 } | |
| 22620 #endif | |
| 22621 | |
| 22584 if (code.is_optimized() && stack_trace.expand_inlined()) { | 22622 if (code.is_optimized() && stack_trace.expand_inlined()) { |
| 22585 code.GetInlinedFunctionsAtReturnAddress(pc_offset, &inlined_functions, | 22623 code.GetInlinedFunctionsAtReturnAddress(pc_offset, &inlined_functions, |
| 22586 &inlined_token_positions); | 22624 &inlined_token_positions); |
| 22587 ASSERT(inlined_functions.length() >= 1); | 22625 ASSERT(inlined_functions.length() >= 1); |
| 22588 for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) { | 22626 for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) { |
| 22589 if (inlined_functions[j]->is_visible() || | 22627 if (inlined_functions[j]->is_visible() || |
| 22590 FLAG_show_invisible_frames) { | 22628 FLAG_show_invisible_frames) { |
| 22591 PrintStackTraceFrame(zone, &buffer, *inlined_functions[j], | 22629 PrintStackTraceFrame(zone, &buffer, *inlined_functions[j], |
| 22592 inlined_token_positions[j], *frame_index); | 22630 inlined_token_positions[j], *frame_index); |
| 22593 (*frame_index)++; | 22631 (*frame_index)++; |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 22927 return UserTag::null(); | 22965 return UserTag::null(); |
| 22928 } | 22966 } |
| 22929 | 22967 |
| 22930 | 22968 |
| 22931 const char* UserTag::ToCString() const { | 22969 const char* UserTag::ToCString() const { |
| 22932 const String& tag_label = String::Handle(label()); | 22970 const String& tag_label = String::Handle(label()); |
| 22933 return tag_label.ToCString(); | 22971 return tag_label.ToCString(); |
| 22934 } | 22972 } |
| 22935 | 22973 |
| 22936 } // namespace dart | 22974 } // namespace dart |
| OLD | NEW |