| 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 |