OLD | NEW |
1 // Copyright (c) 2005, Google Inc. | 1 // Copyright (c) 2005, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 //#define _XOPEN_SOURCE 500 | 55 //#define _XOPEN_SOURCE 500 |
56 | 56 |
57 #include <string.h> // for memcmp | 57 #include <string.h> // for memcmp |
58 #if defined(HAVE_SYS_UCONTEXT_H) | 58 #if defined(HAVE_SYS_UCONTEXT_H) |
59 #include <sys/ucontext.h> | 59 #include <sys/ucontext.h> |
60 #elif defined(HAVE_UCONTEXT_H) | 60 #elif defined(HAVE_UCONTEXT_H) |
61 #include <ucontext.h> // for ucontext_t (and also mcontext_t) | 61 #include <ucontext.h> // for ucontext_t (and also mcontext_t) |
62 #elif defined(HAVE_CYGWIN_SIGNAL_H) | 62 #elif defined(HAVE_CYGWIN_SIGNAL_H) |
63 #include <cygwin/signal.h> | 63 #include <cygwin/signal.h> |
64 typedef ucontext ucontext_t; | 64 typedef ucontext ucontext_t; |
| 65 #elif defined(__ANDROID__) |
| 66 #include <unwind.h> |
65 #endif | 67 #endif |
66 | 68 |
67 | 69 |
68 // Take the example where function Foo() calls function Bar(). For | 70 // Take the example where function Foo() calls function Bar(). For |
69 // many architectures, Bar() is responsible for setting up and tearing | 71 // many architectures, Bar() is responsible for setting up and tearing |
70 // down its own stack frame. In that case, it's possible for the | 72 // down its own stack frame. In that case, it's possible for the |
71 // interrupt to happen when execution is in Bar(), but the stack frame | 73 // interrupt to happen when execution is in Bar(), but the stack frame |
72 // is not properly set up (either before it's done being set up, or | 74 // is not properly set up (either before it's done being set up, or |
73 // after it's been torn down but before Bar() returns). In those | 75 // after it's been torn down but before Bar() returns). In those |
74 // cases, the stack trace cannot see the caller function anymore. | 76 // cases, the stack trace cannot see the caller function anymore. |
(...skipping 27 matching lines...) Expand all Loading... |
102 int return_sp_offset; | 104 int return_sp_offset; |
103 }; | 105 }; |
104 | 106 |
105 | 107 |
106 // The dereferences needed to get the PC from a struct ucontext were | 108 // The dereferences needed to get the PC from a struct ucontext were |
107 // determined at configure time, and stored in the macro | 109 // determined at configure time, and stored in the macro |
108 // PC_FROM_UCONTEXT in config.h. The only thing we need to do here, | 110 // PC_FROM_UCONTEXT in config.h. The only thing we need to do here, |
109 // then, is to do the magic call-unrolling for systems that support it. | 111 // then, is to do the magic call-unrolling for systems that support it. |
110 | 112 |
111 // -- Special case 1: linux x86, for which we have CallUnrollInfo | 113 // -- Special case 1: linux x86, for which we have CallUnrollInfo |
112 #if defined(__linux) && defined(__i386) && defined(__GNUC__) | 114 #if defined(__linux) && defined(__i386) && defined(__GNUC__) && \ |
| 115 !defined(__ANDROID__) |
113 static const CallUnrollInfo callunrollinfo[] = { | 116 static const CallUnrollInfo callunrollinfo[] = { |
114 // Entry to a function: push %ebp; mov %esp,%ebp | 117 // Entry to a function: push %ebp; mov %esp,%ebp |
115 // Top-of-stack contains the caller IP. | 118 // Top-of-stack contains the caller IP. |
116 { 0, | 119 { 0, |
117 {0x55, 0x89, 0xe5}, 3, | 120 {0x55, 0x89, 0xe5}, 3, |
118 0 | 121 0 |
119 }, | 122 }, |
120 // Entry to a function, second instruction: push %ebp; mov %esp,%ebp | 123 // Entry to a function, second instruction: push %ebp; mov %esp,%ebp |
121 // Top-of-stack contains the old frame, caller IP is +4. | 124 // Top-of-stack contains the old frame, caller IP is +4. |
122 { -1, | 125 { -1, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 | 167 |
165 #include "base/logging.h" // for RAW_LOG | 168 #include "base/logging.h" // for RAW_LOG |
166 #ifndef HAVE_CYGWIN_SIGNAL_H | 169 #ifndef HAVE_CYGWIN_SIGNAL_H |
167 typedef int ucontext_t; | 170 typedef int ucontext_t; |
168 #endif | 171 #endif |
169 | 172 |
170 inline void* GetPC(const struct ucontext_t& signal_ucontext) { | 173 inline void* GetPC(const struct ucontext_t& signal_ucontext) { |
171 RAW_LOG(ERROR, "GetPC is not yet implemented on Windows\n"); | 174 RAW_LOG(ERROR, "GetPC is not yet implemented on Windows\n"); |
172 return NULL; | 175 return NULL; |
173 } | 176 } |
| 177 #elif defined(__ANDROID__) |
| 178 typedef struct _Unwind_Context ucontext_t; |
174 | 179 |
| 180 inline void* GetPC(const ucontext_t& signal_ucontext) { |
| 181 // Bionic doesn't export ucontext, see |
| 182 // https://code.google.com/p/android/issues/detail?id=34784. |
| 183 return reinterpret_cast<void*>(_Unwind_GetIP( |
| 184 const_cast<ucontext_t*>(&signal_ucontext))); |
| 185 } |
| 186 // |
175 // Normal cases. If this doesn't compile, it's probably because | 187 // Normal cases. If this doesn't compile, it's probably because |
176 // PC_FROM_UCONTEXT is the empty string. You need to figure out | 188 // PC_FROM_UCONTEXT is the empty string. You need to figure out |
177 // the right value for your system, and add it to the list in | 189 // the right value for your system, and add it to the list in |
178 // configure.ac (or set it manually in your config.h). | 190 // configure.ac (or set it manually in your config.h). |
179 #else | 191 #else |
180 inline void* GetPC(const ucontext_t& signal_ucontext) { | 192 inline void* GetPC(const ucontext_t& signal_ucontext) { |
181 return (void*)signal_ucontext.PC_FROM_UCONTEXT; // defined in config.h | 193 return (void*)signal_ucontext.PC_FROM_UCONTEXT; // defined in config.h |
182 } | 194 } |
183 | 195 |
184 #endif | 196 #endif |
185 | 197 |
186 #endif // BASE_GETPC_H_ | 198 #endif // BASE_GETPC_H_ |
OLD | NEW |