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

Side by Side Diff: base/debug/stack_trace.h

Issue 2361353002: Link stack frames of JNI stubs to JNI callbacks. (Closed)
Patch Set: git cl format Created 4 years, 1 month 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
OLDNEW
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 #ifndef BASE_DEBUG_STACK_TRACE_H_ 5 #ifndef BASE_DEBUG_STACK_TRACE_H_
6 #define BASE_DEBUG_STACK_TRACE_H_ 6 #define BASE_DEBUG_STACK_TRACE_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <iosfwd> 10 #include <iosfwd>
11 #include <string> 11 #include <string>
12 12
13 #include "base/base_export.h" 13 #include "base/base_export.h"
14 #include "base/macros.h"
14 #include "build/build_config.h" 15 #include "build/build_config.h"
15 16
16 #if defined(OS_POSIX) 17 #if defined(OS_POSIX)
17 #include <unistd.h> 18 #include <unistd.h>
18 #endif 19 #endif
19 20
20 #if defined(OS_WIN) 21 #if defined(OS_WIN)
21 struct _EXCEPTION_POINTERS; 22 struct _EXCEPTION_POINTERS;
22 struct _CONTEXT; 23 struct _CONTEXT;
23 #endif 24 #endif
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 // reliable than StackTrace. It should work for debug and profiling builds, 107 // reliable than StackTrace. It should work for debug and profiling builds,
107 // but not for release builds (although there are some exceptions). 108 // but not for release builds (although there are some exceptions).
108 // 109 //
109 // Writes at most |max_depth| frames (instruction pointers) into |out_trace| 110 // Writes at most |max_depth| frames (instruction pointers) into |out_trace|
110 // after skipping |skip_initial| frames. Note that the function itself is not 111 // after skipping |skip_initial| frames. Note that the function itself is not
111 // added to the trace so |skip_initial| should be 0 in most cases. 112 // added to the trace so |skip_initial| should be 0 in most cases.
112 // Returns number of frames written. 113 // Returns number of frames written.
113 BASE_EXPORT size_t TraceStackFramePointers(const void** out_trace, 114 BASE_EXPORT size_t TraceStackFramePointers(const void** out_trace,
114 size_t max_depth, 115 size_t max_depth,
115 size_t skip_initial); 116 size_t skip_initial);
117
118 // Links stack frame |fp| to |parent_fp|, so that during stack unwinding
119 // TraceStackFramePointers() visits |parent_fp| after visiting |fp|.
120 // Both frame pointers must come from __builtin_frame_address().
121 // Destructor restores original linkage of |fp| to avoid corrupting caller's
122 // frame register on return.
123 //
124 // This class can be used to repair broken stack frame chain in cases
125 // when execution flow goes into code built without frame pointers:
126 //
127 // void DoWork() {
128 // Call_SomeLibrary();
129 // }
130 // static __thread void* g_saved_fp;
131 // void Call_SomeLibrary() {
132 // g_saved_fp = __builtin_frame_address(0);
133 // some_library_call(...); // indirectly calls SomeLibrary_Callback()
134 // }
135 // void SomeLibrary_Callback() {
136 // ScopedStackFrameLinker linker(__builtin_frame_address(0), g_saved_fp);
137 // ...
138 // TraceStackFramePointers(...);
139 // }
140 //
141 // This produces the following trace:
142 //
143 // #0 SomeLibrary_Callback()
144 // #1 <address of the code inside SomeLibrary that called #0>
145 // #2 DoWork()
146 // ...rest of the trace...
147 //
148 // SomeLibrary doesn't use frame pointers, so when SomeLibrary_Callback()
149 // is called, stack frame register contains bogus value that becomes callback'
150 // parent frame address. Without ScopedStackFrameLinker unwinding would've
151 // stopped at that bogus frame address yielding just two first frames (#0, #1).
152 // ScopedStackFrameLinker overwrites callback's parent frame address with
153 // Call_SomeLibrary's frame, so unwinder produces full trace without even
154 // noticing that stack frame chain was broken.
155 class BASE_EXPORT ScopedStackFrameLinker {
156 public:
157 ScopedStackFrameLinker(void* fp, void* parent_fp);
158 ~ScopedStackFrameLinker();
159
160 private:
161 void* fp_;
162 void* parent_fp_;
163 void* original_parent_fp_;
164
165 DISALLOW_COPY_AND_ASSIGN(ScopedStackFrameLinker);
166 };
167
116 #endif // HAVE_TRACE_STACK_FRAME_POINTERS 168 #endif // HAVE_TRACE_STACK_FRAME_POINTERS
117 169
118 namespace internal { 170 namespace internal {
119 171
120 #if defined(OS_POSIX) && !defined(OS_ANDROID) 172 #if defined(OS_POSIX) && !defined(OS_ANDROID)
121 // POSIX doesn't define any async-signal safe function for converting 173 // POSIX doesn't define any async-signal safe function for converting
122 // an integer to ASCII. We'll have to define our own version. 174 // an integer to ASCII. We'll have to define our own version.
123 // itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the 175 // itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the
124 // conversion was successful or NULL otherwise. It never writes more than "sz" 176 // conversion was successful or NULL otherwise. It never writes more than "sz"
125 // bytes. Output will be truncated as needed, and a NUL character is always 177 // bytes. Output will be truncated as needed, and a NUL character is always
126 // appended. 178 // appended.
127 BASE_EXPORT char *itoa_r(intptr_t i, 179 BASE_EXPORT char *itoa_r(intptr_t i,
128 char *buf, 180 char *buf,
129 size_t sz, 181 size_t sz,
130 int base, 182 int base,
131 size_t padding); 183 size_t padding);
132 #endif // defined(OS_POSIX) && !defined(OS_ANDROID) 184 #endif // defined(OS_POSIX) && !defined(OS_ANDROID)
133 185
134 } // namespace internal 186 } // namespace internal
135 187
136 } // namespace debug 188 } // namespace debug
137 } // namespace base 189 } // namespace base
138 190
139 #endif // BASE_DEBUG_STACK_TRACE_H_ 191 #endif // BASE_DEBUG_STACK_TRACE_H_
OLDNEW
« no previous file with comments | « base/android/jni_generator/testSingleJNIAdditionalImport.golden ('k') | base/debug/stack_trace.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698