Planeshift
|
00001 // Copyright (c) 2010, Google Inc. 00002 // All rights reserved. 00003 // 00004 // Redistribution and use in source and binary forms, with or without 00005 // modification, are permitted provided that the following conditions are 00006 // met: 00007 // 00008 // * Redistributions of source code must retain the above copyright 00009 // notice, this list of conditions and the following disclaimer. 00010 // * Redistributions in binary form must reproduce the above 00011 // copyright notice, this list of conditions and the following disclaimer 00012 // in the documentation and/or other materials provided with the 00013 // distribution. 00014 // * Neither the name of Google Inc. nor the names of its 00015 // contributors may be used to endorse or promote products derived from 00016 // this software without specific prior written permission. 00017 // 00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00022 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00023 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00024 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 00030 // linux_dumper.h: Define the google_breakpad::LinuxDumper class, which 00031 // is a base class for extracting information of a crashed process. It 00032 // was originally a complete implementation using the ptrace API, but 00033 // has been refactored to allow derived implementations supporting both 00034 // ptrace and core dump. A portion of the original implementation is now 00035 // in google_breakpad::LinuxPtraceDumper (see linux_ptrace_dumper.h for 00036 // details). 00037 00038 #ifndef CLIENT_LINUX_MINIDUMP_WRITER_LINUX_DUMPER_H_ 00039 #define CLIENT_LINUX_MINIDUMP_WRITER_LINUX_DUMPER_H_ 00040 00041 #include <elf.h> 00042 #include <linux/limits.h> 00043 #include <stdint.h> 00044 #include <sys/types.h> 00045 #include <sys/user.h> 00046 00047 #include "common/memory.h" 00048 #include "google_breakpad/common/minidump_format.h" 00049 00050 namespace google_breakpad { 00051 00052 #if defined(__i386) || defined(__x86_64) 00053 typedef typeof(((struct user*) 0)->u_debugreg[0]) debugreg_t; 00054 #endif 00055 00056 // Typedef for our parsing of the auxv variables in /proc/pid/auxv. 00057 #if defined(__i386) || defined(__ARM_EABI__) 00058 typedef Elf32_auxv_t elf_aux_entry; 00059 #elif defined(__x86_64) 00060 typedef Elf64_auxv_t elf_aux_entry; 00061 #endif 00062 00063 typedef typeof(((elf_aux_entry*) 0)->a_un.a_val) elf_aux_val_t; 00064 00065 // When we find the VDSO mapping in the process's address space, this 00066 // is the name we use for it when writing it to the minidump. 00067 // This should always be less than NAME_MAX! 00068 const char kLinuxGateLibraryName[] = "linux-gate.so"; 00069 00070 // We produce one of these structures for each thread in the crashed process. 00071 struct ThreadInfo { 00072 pid_t tgid; // thread group id 00073 pid_t ppid; // parent process 00074 00075 uintptr_t stack_pointer; // thread stack pointer 00076 00077 00078 #if defined(__i386) || defined(__x86_64) 00079 user_regs_struct regs; 00080 user_fpregs_struct fpregs; 00081 static const unsigned kNumDebugRegisters = 8; 00082 debugreg_t dregs[8]; 00083 #if defined(__i386) 00084 user_fpxregs_struct fpxregs; 00085 #endif // defined(__i386) 00086 00087 #elif defined(__ARM_EABI__) 00088 // Mimicking how strace does this(see syscall.c, search for GETREGS) 00089 struct user_regs regs; 00090 struct user_fpregs fpregs; 00091 #endif 00092 }; 00093 00094 // One of these is produced for each mapping in the process (i.e. line in 00095 // /proc/$x/maps). 00096 struct MappingInfo { 00097 uintptr_t start_addr; 00098 size_t size; 00099 size_t offset; // offset into the backed file. 00100 char name[NAME_MAX]; 00101 }; 00102 00103 class LinuxDumper { 00104 public: 00105 explicit LinuxDumper(pid_t pid); 00106 00107 virtual ~LinuxDumper(); 00108 00109 // Parse the data for |threads| and |mappings|. 00110 virtual bool Init(); 00111 00112 // Return true if the dumper performs a post-mortem dump. 00113 virtual bool IsPostMortem() const = 0; 00114 00115 // Suspend/resume all threads in the given process. 00116 virtual bool ThreadsSuspend() = 0; 00117 virtual bool ThreadsResume() = 0; 00118 00119 // Read information about the |index|-th thread of |threads_|. 00120 // Returns true on success. One must have called |ThreadsSuspend| first. 00121 virtual bool GetThreadInfoByIndex(size_t index, ThreadInfo* info) = 0; 00122 00123 // These are only valid after a call to |Init|. 00124 const wasteful_vector<pid_t> &threads() { return threads_; } 00125 const wasteful_vector<MappingInfo*> &mappings() { return mappings_; } 00126 const MappingInfo* FindMapping(const void* address) const; 00127 const wasteful_vector<elf_aux_val_t>& auxv() { return auxv_; } 00128 00129 // Find a block of memory to take as the stack given the top of stack pointer. 00130 // stack: (output) the lowest address in the memory area 00131 // stack_len: (output) the length of the memory area 00132 // stack_top: the current top of the stack 00133 bool GetStackInfo(const void** stack, size_t* stack_len, uintptr_t stack_top); 00134 00135 PageAllocator* allocator() { return &allocator_; } 00136 00137 // Copy content of |length| bytes from a given process |child|, 00138 // starting from |src|, into |dest|. 00139 virtual void CopyFromProcess(void* dest, pid_t child, const void* src, 00140 size_t length) = 0; 00141 00142 // Builds a proc path for a certain pid for a node (/proc/<pid>/<node>). 00143 // |path| is a character array of at least NAME_MAX bytes to return the 00144 // result.|node| is the final node without any slashes. Returns true on 00145 // success. 00146 virtual bool BuildProcPath(char* path, pid_t pid, const char* node) const = 0; 00147 00148 // Generate a File ID from the .text section of a mapped entry. 00149 // If not a member, mapping_id is ignored. 00150 bool ElfFileIdentifierForMapping(const MappingInfo& mapping, 00151 bool member, 00152 unsigned int mapping_id, 00153 uint8_t identifier[sizeof(MDGUID)]); 00154 00155 uintptr_t crash_address() const { return crash_address_; } 00156 void set_crash_address(uintptr_t crash_address) { 00157 crash_address_ = crash_address; 00158 } 00159 00160 int crash_signal() const { return crash_signal_; } 00161 void set_crash_signal(int crash_signal) { crash_signal_ = crash_signal; } 00162 00163 pid_t crash_thread() const { return crash_thread_; } 00164 void set_crash_thread(pid_t crash_thread) { crash_thread_ = crash_thread; } 00165 00166 protected: 00167 bool ReadAuxv(); 00168 00169 virtual bool EnumerateMappings(); 00170 00171 virtual bool EnumerateThreads() = 0; 00172 00173 // For the case where a running program has been deleted, it'll show up in 00174 // /proc/pid/maps as "/path/to/program (deleted)". If this is the case, then 00175 // see if '/path/to/program (deleted)' matches /proc/pid/exe and return 00176 // /proc/pid/exe in |path| so ELF identifier generation works correctly. This 00177 // also checks to see if '/path/to/program (deleted)' exists, so it does not 00178 // get fooled by a poorly named binary. 00179 // For programs that don't end with ' (deleted)', this is a no-op. 00180 // This assumes |path| is a buffer with length NAME_MAX. 00181 // Returns true if |path| is modified. 00182 bool HandleDeletedFileInMapping(char* path) const; 00183 00184 // ID of the crashed process. 00185 const pid_t pid_; 00186 00187 // Virtual address at which the process crashed. 00188 uintptr_t crash_address_; 00189 00190 // Signal that terminated the crashed process. 00191 int crash_signal_; 00192 00193 // ID of the crashed thread. 00194 pid_t crash_thread_; 00195 00196 mutable PageAllocator allocator_; 00197 00198 // IDs of all the threads. 00199 wasteful_vector<pid_t> threads_; 00200 00201 // Info from /proc/<pid>/maps. 00202 wasteful_vector<MappingInfo*> mappings_; 00203 00204 // Info from /proc/<pid>/auxv 00205 wasteful_vector<elf_aux_val_t> auxv_; 00206 }; 00207 00208 } // namespace google_breakpad 00209 00210 #endif // CLIENT_LINUX_HANDLER_LINUX_DUMPER_H_