1 // Copyright (c) 2007, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // Author: Alfred Peng 31 32 #ifndef CLIENT_SOLARIS_HANDLER_SOLARIS_LWP_H__ 33 #define CLIENT_SOLARIS_HANDLER_SOLARIS_LWP_H__ 34 35 #if defined(sparc) || defined(__sparc) 36 #define TARGET_CPU_SPARC 1 37 #elif defined(i386) || defined(__i386) 38 #define TARGET_CPU_X86 1 39 #else 40 #error "cannot determine cpu type" 41 #endif 42 43 #include <signal.h> 44 #include <stdint.h> 45 #include <sys/user.h> 46 #include <ucontext.h> 47 48 #ifndef _KERNEL 49 #define _KERNEL 50 #define MUST_UNDEF_KERNEL 51 #endif // _KERNEL 52 #include <sys/procfs.h> 53 #ifdef MUST_UNDEF_KERNEL 54 #undef _KERNEL 55 #undef MUST_UNDEF_KERNEL 56 #endif // MUST_UNDEF_KERNEL 57 58 namespace google_breakpad { 59 60 // Max module path name length. 61 static const int kMaxModuleNameLength = 256; 62 63 // Holding infomaton about a module in the process. 64 struct ModuleInfo { 65 char name[kMaxModuleNameLength]; 66 uintptr_t start_addr; 67 int size; 68 }; 69 70 // A callback to run when getting a lwp in the process. 71 // Return true will go on to the next lwp while return false will stop the 72 // iteration. 73 typedef bool (*LwpCallback)(lwpstatus_t* lsp, void *context); 74 75 // A callback to run when a new module is found in the process. 76 // Return true will go on to the next module while return false will stop the 77 // iteration. 78 typedef bool (*ModuleCallback)(const ModuleInfo &module_info, void *context); 79 80 // A callback to run when getting a lwpid in the process. 81 // Return true will go on to the next lwp while return false will stop the 82 // iteration. 83 typedef bool (*LwpidCallback)(int lwpid, void *context); 84 85 // Holding the callback information. 86 template<class CallbackFunc> 87 struct CallbackParam { 88 // Callback function address. 89 CallbackFunc call_back; 90 // Callback context; 91 void *context; 92 CallbackParamCallbackParam93 CallbackParam() : call_back(NULL), context(NULL) { 94 } 95 CallbackParamCallbackParam96 CallbackParam(CallbackFunc func, void *func_context) : 97 call_back(func), context(func_context) { 98 } 99 }; 100 101 /////////////////////////////////////////////////////////////////////////////// 102 103 // 104 // SolarisLwp 105 // 106 // Provides handy support for operation on Solaris lwps. 107 // It uses proc file system to get lwp information. 108 // 109 // TODO(Alfred): Currently it only supports x86. Add SPARC support. 110 // 111 class SolarisLwp { 112 public: 113 // Create a SolarisLwp instance to list all the lwps in a process. 114 explicit SolarisLwp(int pid); 115 ~SolarisLwp(); 116 getpid()117 int getpid() const { return this->pid_; } 118 119 // Control all the lwps in the process. 120 // Return the number of suspended/resumed lwps in the process. 121 // Return -1 means failed to control lwps. 122 int ControlAllLwps(bool suspend); 123 124 // Get the count of lwps in the process. 125 // Return -1 means error. 126 int GetLwpCount() const; 127 128 // Iterate the lwps of process. 129 // Whenever there is a lwp found, the callback will be invoked to process 130 // the information. 131 // Return the callback return value or -1 on error. 132 int Lwp_iter_all(int pid, CallbackParam<LwpCallback> *callback_param) const; 133 134 // Get the module count of the current process. 135 int GetModuleCount() const; 136 137 // Get the mapped modules in the address space. 138 // Whenever a module is found, the callback will be invoked to process the 139 // information. 140 // Return how may modules are found. 141 int ListModules(CallbackParam<ModuleCallback> *callback_param) const; 142 143 // Get the bottom of the stack from esp. 144 uintptr_t GetLwpStackBottom(uintptr_t current_esp) const; 145 146 // Finds a signal context on the stack given the ebp of our signal handler. 147 bool FindSigContext(uintptr_t sighandler_ebp, ucontext_t **sig_ctx); 148 149 private: 150 // Check if the address is a valid virtual address. 151 bool IsAddressMapped(uintptr_t address) const; 152 153 private: 154 // The pid of the process we are listing lwps. 155 int pid_; 156 }; 157 158 } // namespace google_breakpad 159 160 #endif // CLIENT_SOLARIS_HANDLER_SOLARIS_LWP_H__ 161