OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/debug/stack_trace.h" | 5 #include "base/debug/stack_trace.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <signal.h> | 9 #include <signal.h> |
10 #include <stddef.h> | 10 #include <stddef.h> |
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
736 #endif | 736 #endif |
737 } | 737 } |
738 | 738 |
739 #if !defined(__UCLIBC__) | 739 #if !defined(__UCLIBC__) |
740 void StackTrace::OutputToStream(std::ostream* os) const { | 740 void StackTrace::OutputToStream(std::ostream* os) const { |
741 StreamBacktraceOutputHandler handler(os); | 741 StreamBacktraceOutputHandler handler(os); |
742 ProcessBacktrace(trace_, count_, &handler); | 742 ProcessBacktrace(trace_, count_, &handler); |
743 } | 743 } |
744 #endif | 744 #endif |
745 | 745 |
746 #if HAVE_TRACE_STACK_FRAME_POINTERS | |
747 | |
748 size_t TraceStackFramePointers(const void** out_trace, | |
749 size_t max_depth, | |
750 size_t skip_initial) { | |
751 uintptr_t fp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0)); | |
Nico
2016/04/18 19:42:05
nit: call this sp
Dmitry Skiba
2016/04/20 16:32:56
Done.
| |
752 | |
753 size_t depth = 0; | |
754 while (fp && depth < max_depth) { | |
755 if (skip_initial != 0) { | |
756 skip_initial--; | |
757 } else { | |
758 out_trace[depth++] = reinterpret_cast<const void**>(fp)[1]; | |
Nico
2016/04/18 19:42:05
you treat fp as void** almost everywhere, consider
Primiano Tucci (use gerrit)
2016/04/18 20:18:07
the frame pointer can be invalid even at this stag
Dmitry Skiba
2016/04/20 16:32:56
Hmm, since I don't have next_fp at that point, I c
Dmitry Skiba
2016/04/20 16:32:56
So we have these casts:
reinterpret_cast<uintptr_
| |
759 } | |
760 | |
761 // Find out next frame pointer | |
762 // (heuristics are from TCMalloc's stacktrace functions) | |
763 { | |
Primiano Tucci (use gerrit)
2016/04/18 20:18:08
why this is inside a scope? Is there an if missing
Dmitry Skiba
2016/04/20 16:32:56
Done.
| |
764 uintptr_t next_fp = reinterpret_cast<const uintptr_t*>(fp)[0]; | |
765 | |
766 // With the stack growing downwards, older stack frame must be | |
767 // at a greater address that the current one. | |
768 if (next_fp <= fp) break; | |
Primiano Tucci (use gerrit)
2016/04/18 20:18:08
I think these checks should happen before you dere
Dmitry Skiba
2016/04/20 16:32:56
But this also dereferences fp, next_fp is fp[1].
| |
769 | |
770 // Assume stack frames larger than 100,000 bytes are bogus. | |
771 if (next_fp - fp > 100000) break; | |
772 | |
773 // Check alignment. | |
774 if (next_fp & (sizeof(void*) - 1)) break; | |
775 | |
776 fp = next_fp; | |
777 } | |
778 } | |
779 | |
780 return depth; | |
781 } | |
782 | |
783 #endif // HAVE_TRACE_STACK_FRAME_POINTERS | |
784 | |
746 namespace internal { | 785 namespace internal { |
747 | 786 |
748 // NOTE: code from sandbox/linux/seccomp-bpf/demo.cc. | 787 // NOTE: code from sandbox/linux/seccomp-bpf/demo.cc. |
749 char* itoa_r(intptr_t i, char* buf, size_t sz, int base, size_t padding) { | 788 char* itoa_r(intptr_t i, char* buf, size_t sz, int base, size_t padding) { |
750 // Make sure we can write at least one NUL byte. | 789 // Make sure we can write at least one NUL byte. |
751 size_t n = 1; | 790 size_t n = 1; |
752 if (n > sz) | 791 if (n > sz) |
753 return NULL; | 792 return NULL; |
754 | 793 |
755 if (base < 2 || base > 16) { | 794 if (base < 2 || base > 16) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
804 *ptr = *start; | 843 *ptr = *start; |
805 *start++ = ch; | 844 *start++ = ch; |
806 } | 845 } |
807 return buf; | 846 return buf; |
808 } | 847 } |
809 | 848 |
810 } // namespace internal | 849 } // namespace internal |
811 | 850 |
812 } // namespace debug | 851 } // namespace debug |
813 } // namespace base | 852 } // namespace base |
OLD | NEW |