OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 "platform/address_sanitizer.h" | 5 #include "platform/address_sanitizer.h" |
6 #include "platform/memory_sanitizer.h" | 6 #include "platform/memory_sanitizer.h" |
7 #include "platform/utils.h" | 7 #include "platform/utils.h" |
8 | 8 |
9 #include "vm/allocation.h" | 9 #include "vm/allocation.h" |
10 #include "vm/atomic.h" | 10 #include "vm/atomic.h" |
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 return reinterpret_cast<uintptr_t>(_ReturnAddress()); | 937 return reinterpret_cast<uintptr_t>(_ReturnAddress()); |
938 } | 938 } |
939 #else | 939 #else |
940 static uintptr_t __attribute__((noinline)) GetProgramCounter() { | 940 static uintptr_t __attribute__((noinline)) GetProgramCounter() { |
941 return reinterpret_cast<uintptr_t>( | 941 return reinterpret_cast<uintptr_t>( |
942 __builtin_extract_return_addr(__builtin_return_address(0))); | 942 __builtin_extract_return_addr(__builtin_return_address(0))); |
943 } | 943 } |
944 #endif | 944 #endif |
945 | 945 |
946 | 946 |
| 947 void Profiler::DumpStackTrace(void* context) { |
| 948 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) |
| 949 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |
| 950 mcontext_t mcontext = ucontext->uc_mcontext; |
| 951 uword pc = SignalHandler::GetProgramCounter(mcontext); |
| 952 uword fp = SignalHandler::GetFramePointer(mcontext); |
| 953 uword sp = SignalHandler::GetCStackPointer(mcontext); |
| 954 DumpStackTrace(true, sp, fp, pc); |
| 955 #else |
| 956 // TODO(fschneider): Add support for more platforms. |
| 957 // Do nothing on unsupported platforms. |
| 958 #endif |
| 959 } |
| 960 |
| 961 |
947 void Profiler::DumpStackTrace(bool native_stack_trace) { | 962 void Profiler::DumpStackTrace(bool native_stack_trace) { |
| 963 uintptr_t sp = Thread::GetCurrentStackPointer(); |
| 964 uintptr_t fp = 0; |
| 965 uintptr_t pc = GetProgramCounter(); |
| 966 COPY_FP_REGISTER(fp); |
| 967 DumpStackTrace(native_stack_trace, sp, fp, pc); |
| 968 } |
| 969 |
| 970 |
| 971 void Profiler::DumpStackTrace(bool native_stack_trace, |
| 972 uword sp, |
| 973 uword fp, |
| 974 uword pc) { |
948 // Allow only one stack trace to prevent recursively printing stack traces if | 975 // Allow only one stack trace to prevent recursively printing stack traces if |
949 // we hit an assert while printing the stack. | 976 // we hit an assert while printing the stack. |
950 static uintptr_t started_dump = 0; | 977 static uintptr_t started_dump = 0; |
951 if (AtomicOperations::FetchAndIncrement(&started_dump) != 0) { | 978 if (AtomicOperations::FetchAndIncrement(&started_dump) != 0) { |
952 OS::PrintErr("Aborting re-entrant request for stack trace.\n"); | 979 OS::PrintErr("Aborting re-entrant request for stack trace.\n"); |
953 return; | 980 return; |
954 } | 981 } |
955 | 982 |
956 Thread* thread = Thread::Current(); | 983 Thread* thread = Thread::Current(); |
957 if (thread == NULL) { | 984 if (thread == NULL) { |
958 return; | 985 return; |
959 } | 986 } |
960 OSThread* os_thread = thread->os_thread(); | 987 OSThread* os_thread = thread->os_thread(); |
961 ASSERT(os_thread != NULL); | 988 ASSERT(os_thread != NULL); |
962 Isolate* isolate = thread->isolate(); | 989 Isolate* isolate = thread->isolate(); |
963 if (!CheckIsolate(isolate)) { | 990 if (!CheckIsolate(isolate)) { |
964 return; | 991 return; |
965 } | 992 } |
966 | 993 |
967 const bool exited_dart_code = thread->HasExitedDartCode(); | 994 const bool exited_dart_code = thread->HasExitedDartCode(); |
968 | 995 |
969 OS::PrintErr("Dumping %s stack trace for thread %" Px "\n", | 996 OS::PrintErr("Dumping %s stack trace for thread %" Px "\n", |
970 native_stack_trace ? "native" : "dart-only", | 997 native_stack_trace ? "native" : "dart-only", |
971 OSThread::ThreadIdToIntPtr(os_thread->trace_id())); | 998 OSThread::ThreadIdToIntPtr(os_thread->trace_id())); |
972 | 999 |
973 uintptr_t sp = Thread::GetCurrentStackPointer(); | |
974 uintptr_t fp = 0; | |
975 uintptr_t pc = GetProgramCounter(); | |
976 | |
977 COPY_FP_REGISTER(fp); | |
978 | |
979 uword stack_lower = 0; | 1000 uword stack_lower = 0; |
980 uword stack_upper = 0; | 1001 uword stack_upper = 0; |
981 | 1002 |
982 if (!InitialRegisterCheck(pc, fp, sp)) { | 1003 if (!InitialRegisterCheck(pc, fp, sp)) { |
983 OS::PrintErr("Stack dump aborted because InitialRegisterCheck.\n"); | 1004 OS::PrintErr("Stack dump aborted because InitialRegisterCheck.\n"); |
984 return; | 1005 return; |
985 } | 1006 } |
986 | 1007 |
987 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower, | 1008 if (!GetAndValidateIsolateStackBounds(thread, fp, sp, &stack_lower, |
988 &stack_upper)) { | 1009 &stack_upper)) { |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1529 | 1550 |
1530 | 1551 |
1531 ProcessedSampleBuffer::ProcessedSampleBuffer() | 1552 ProcessedSampleBuffer::ProcessedSampleBuffer() |
1532 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { | 1553 : code_lookup_table_(new CodeLookupTable(Thread::Current())) { |
1533 ASSERT(code_lookup_table_ != NULL); | 1554 ASSERT(code_lookup_table_ != NULL); |
1534 } | 1555 } |
1535 | 1556 |
1536 #endif // !PRODUCT | 1557 #endif // !PRODUCT |
1537 | 1558 |
1538 } // namespace dart | 1559 } // namespace dart |
OLD | NEW |