19abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// Copyright (c) 2007, Google Inc. 29abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// All rights reserved. 39abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// 49abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// Redistribution and use in source and binary forms, with or without 59abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// modification, are permitted provided that the following conditions are 69abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// met: 79abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// 89abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// * Redistributions of source code must retain the above copyright 99abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// notice, this list of conditions and the following disclaimer. 109abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// * Redistributions in binary form must reproduce the above 119abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// copyright notice, this list of conditions and the following disclaimer 129abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// in the documentation and/or other materials provided with the 139abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// distribution. 149abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// * Neither the name of Google Inc. nor the names of its 159abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// contributors may be used to endorse or promote products derived from 169abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// this software without specific prior written permission. 179abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// 189abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 199abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 209abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 219abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 229abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 239abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 249abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 259abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 269abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 279abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 289abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 299abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 309abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// Author: Alfred Peng 319abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 329abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include <fcntl.h> 33dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#include <sys/frame.h> 349abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include <sys/stat.h> 359abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include <sys/types.h> 369abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include <sys/utsname.h> 379abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include <sys/wait.h> 389abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include <unistd.h> 399abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 409abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include <cstdlib> 419abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include <ctime> 429abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 439abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include "client/solaris/handler/minidump_generator.h" 449abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include "client/minidump_file_writer-inl.h" 459abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai#include "common/solaris/file_id.h" 469abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 47dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczareknamespace { 48dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 49dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekusing namespace google_breakpad; 50dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 51dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// Argument for the writer function. 52dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekstruct WriterArgument { 53dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MinidumpFileWriter *minidump_writer; 54dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 55dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // Pid of the lwp who called WriteMinidumpToFile 56dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int requester_pid; 57dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 58dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // The stack bottom of the lwp which caused the dump. 59dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // Mainly used to find the lwp id of the crashed lwp since signal 60dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // handler may not be called in the lwp who caused it. 61dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek uintptr_t crashed_stack_bottom; 62dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 63dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // Id of the crashing lwp. 64dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int crashed_lwpid; 65dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 66dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // Signal number when crash happened. Can be 0 if this is a requested dump. 67dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int signo; 68dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 69dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // The ebp of the signal handler frame on x86. Can be 0 if this is a 70dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // requested dump. 71dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek uintptr_t sighandler_ebp; 72dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 73dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // User context when crash happens. Can be NULL if this is a requested dump. 74dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // This is actually an out parameter, but it will be filled in at the start 75dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // of the writer LWP. 76dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek ucontext_t *sig_ctx; 77dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 78dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // Used to get information about the lwps. 79dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek SolarisLwp *lwp_lister; 80dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek}; 81dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 82dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// Holding context information for the callback of finding the crashing lwp. 83dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekstruct FindCrashLwpContext { 84dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const SolarisLwp *lwp_lister; 85dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek uintptr_t crashing_stack_bottom; 86dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int crashing_lwpid; 879abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 88dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek FindCrashLwpContext() : 89dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek lwp_lister(NULL), 90dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek crashing_stack_bottom(0UL), 91dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek crashing_lwpid(-1) { 92dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } 93dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek}; 94dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 95dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// Callback for list lwps. 96dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// It will compare the stack bottom of the provided lwp with the stack 97dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// bottom of the crashed lwp, it they are eqaul, this lwp is the one 98dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// who crashed. 99dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool IsLwpCrashedCallback(lwpstatus_t *lsp, void *context) { 100dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek FindCrashLwpContext *crashing_context = 101dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek static_cast<FindCrashLwpContext *>(context); 102dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const SolarisLwp *lwp_lister = crashing_context->lwp_lister; 103dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const prgregset_t *gregs = &(lsp->pr_reg); 104dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#if TARGET_CPU_SPARC 105dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek uintptr_t last_ebp = (*gregs)[R_FP]; 106dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#elif TARGET_CPU_X86 107dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek uintptr_t last_ebp = (*gregs)[EBP]; 108dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#endif 109dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek uintptr_t stack_bottom = lwp_lister->GetLwpStackBottom(last_ebp); 110dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (stack_bottom > last_ebp && 111dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek stack_bottom == crashing_context->crashing_stack_bottom) { 112dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // Got it. Stop iteration. 113dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek crashing_context->crashing_lwpid = lsp->pr_lwpid; 114dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return false; 115dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } 116dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 117dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return true; 1189abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 1199abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 120dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// Find the crashing lwpid. 121dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// This is done based on stack bottom comparing. 122dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekint FindCrashingLwp(uintptr_t crashing_stack_bottom, 123dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int requester_pid, 124dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const SolarisLwp *lwp_lister) { 125dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek FindCrashLwpContext context; 126dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context.lwp_lister = lwp_lister; 127dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context.crashing_stack_bottom = crashing_stack_bottom; 128dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek CallbackParam<LwpCallback> callback_param(IsLwpCrashedCallback, 129dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek &context); 130dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek lwp_lister->Lwp_iter_all(lwp_lister->getpid(), &callback_param); 131dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return context.crashing_lwpid; 1329abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 1339abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 134dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteLwpStack(const SolarisLwp *lwp_lister, 135dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek uintptr_t last_esp, 136dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek UntypedMDRVA *memory, 137dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDMemoryDescriptor *loc) { 138dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek uintptr_t stack_bottom = lwp_lister->GetLwpStackBottom(last_esp); 139ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (stack_bottom >= last_esp) { 1409abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai int size = stack_bottom - last_esp; 1419abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (size > 0) { 1429abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (!memory->Allocate(size)) 1439abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 1449abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai memory->Copy(reinterpret_cast<void *>(last_esp), size); 1459abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai loc->start_of_memory_range = last_esp; 1469abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai loc->memory = memory->location(); 1479abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 1489abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return true; 1499abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 1509abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 1519abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 1529abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 153ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai#if TARGET_CPU_SPARC 154dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteContext(MDRawContextSPARC *context, ucontext_t *sig_ctx) { 155dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek assert(sig_ctx != NULL); 156dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int* regs = sig_ctx->uc_mcontext.gregs; 157dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->context_flags = MD_CONTEXT_SPARC_FULL; 158dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 159dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->ccr = (unsigned int)(regs[0]); 160dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->pc = (unsigned int)(regs[REG_PC]); 161dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->npc = (unsigned int)(regs[REG_nPC]); 162dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->y = (unsigned int)(regs[REG_Y]); 163dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->asi = (unsigned int)(regs[19]); 164dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->fprs = (unsigned int)(regs[20]); 165dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 166dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek for ( int i = 0 ; i < 32; ++i ) { 167dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->g_r[i] = 0; 168dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } 169dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 170dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek for ( int i = 1 ; i < 16; ++i ) { 171dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->g_r[i] = (uintptr_t)(sig_ctx->uc_mcontext.gregs[i + 3]); 172dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } 173dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->g_r[30] = (uintptr_t)(((struct frame *)context->g_r[14])->fr_savfp); 174dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 175dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return true; 176dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek} 177dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 178dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteContext(MDRawContextSPARC *context, prgregset_t regs, 179dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek prfpregset_t *fp_regs) { 180ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!context || !regs) 181ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 182ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 183ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai context->context_flags = MD_CONTEXT_SPARC_FULL; 184ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 185dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->ccr = (uintptr_t)(regs[32]); 186dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->pc = (uintptr_t)(regs[R_PC]); 187dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->npc = (uintptr_t)(regs[R_nPC]); 188dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->y = (uintptr_t)(regs[R_Y]); 189dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->asi = (uintptr_t)(regs[36]); 190dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->fprs = (uintptr_t)(regs[37]); 191ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai for ( int i = 0 ; i < 32 ; ++i ){ 192dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context->g_r[i] = (uintptr_t)(regs[i]); 193ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai } 194ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 195ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return true; 196ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai} 197ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai#elif TARGET_CPU_X86 198dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteContext(MDRawContextX86 *context, prgregset_t regs, 199dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek prfpregset_t *fp_regs) { 2009abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (!context || !regs) 2019abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 2029abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 2039abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->context_flags = MD_CONTEXT_X86_FULL; 2049abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 2059abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->cs = regs[CS]; 2069abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->ds = regs[DS]; 2079abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->es = regs[ES]; 2089abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->fs = regs[FS]; 2099abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->gs = regs[GS]; 2109abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->ss = regs[SS]; 2119abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->edi = regs[EDI]; 2129abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->esi = regs[ESI]; 2139abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->ebx = regs[EBX]; 2149abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->edx = regs[EDX]; 2159abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->ecx = regs[ECX]; 2169abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->eax = regs[EAX]; 2179abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->ebp = regs[EBP]; 2189abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->eip = regs[EIP]; 2199abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->esp = regs[UESP]; 2209abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context->eflags = regs[EFL]; 2219abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 2229abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return true; 2239abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 224ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai#endif /* TARGET_CPU_XXX */ 2259abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 226dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// Write information about a crashed Lwp. 227dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// When a lwp crash, kernel will write something on the stack for processing 228dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// signal. This makes the current stack not reliable, and our stack walker 229dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// won't figure out the whole call stack for this. So we write the stack at the 230dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// time of the crash into the minidump file, not the current stack. 231dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteCrashedLwpStream(MinidumpFileWriter *minidump_writer, 232dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const WriterArgument *writer_args, 233dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const lwpstatus_t *lsp, 234dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDRawThread *lwp) { 235dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek assert(writer_args->sig_ctx != NULL); 236dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 237dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek lwp->thread_id = lsp->pr_lwpid; 238dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 239dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#if TARGET_CPU_SPARC 240dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek UntypedMDRVA memory(minidump_writer); 241dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!WriteLwpStack(writer_args->lwp_lister, 242dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->sig_ctx->uc_mcontext.gregs[REG_O6], 243dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek &memory, 244dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek &lwp->stack)) 245dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return false; 246dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 247dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawContextSPARC> context(minidump_writer); 248dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!context.Allocate()) 249dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return false; 250dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek lwp->thread_context = context.location(); 251dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek memset(context.get(), 0, sizeof(MDRawContextSPARC)); 252dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return WriteContext(context.get(), writer_args->sig_ctx); 253dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#elif TARGET_CPU_X86 254dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek UntypedMDRVA memory(minidump_writer); 255dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!WriteLwpStack(writer_args->lwp_lister, 256dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->sig_ctx->uc_mcontext.gregs[UESP], 257dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek &memory, 258dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek &lwp->stack)) 259dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return false; 260dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 261dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawContextX86> context(minidump_writer); 262dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!context.Allocate()) 263dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return false; 264dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek lwp->thread_context = context.location(); 265dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek memset(context.get(), 0, sizeof(MDRawContextX86)); 266dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return WriteContext(context.get(), 267dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek (int *)&writer_args->sig_ctx->uc_mcontext.gregs, 268dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek &writer_args->sig_ctx->uc_mcontext.fpregs); 269dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#endif 270dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek} 271dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 272dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteLwpStream(MinidumpFileWriter *minidump_writer, 273dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const SolarisLwp *lwp_lister, 274dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const lwpstatus_t *lsp, MDRawThread *lwp) { 2759abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai prfpregset_t fp_regs = lsp->pr_fpreg; 276dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const prgregset_t *gregs = &(lsp->pr_reg); 277dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek UntypedMDRVA memory(minidump_writer); 278ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai#if TARGET_CPU_SPARC 279dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!WriteLwpStack(lwp_lister, 280dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek (*gregs)[R_SP], 2819abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai &memory, 2829abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai &lwp->stack)) 2839abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 2849abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 2859abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai // Write context 286dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawContextSPARC> context(minidump_writer); 287ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!context.Allocate()) 288ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 289ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // should be the thread_id 290ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai lwp->thread_id = lsp->pr_lwpid; 291ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai lwp->thread_context = context.location(); 292ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai memset(context.get(), 0, sizeof(MDRawContextSPARC)); 293ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai#elif TARGET_CPU_X86 294dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!WriteLwpStack(lwp_lister, 295dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek (*gregs)[UESP], 296ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai &memory, 297ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai &lwp->stack)) 298ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 299ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai 300ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // Write context 301dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawContextX86> context(minidump_writer); 3029abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (!context.Allocate()) 3039abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 304ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // should be the thread_id 305ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai lwp->thread_id = lsp->pr_lwpid; 3069abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai lwp->thread_context = context.location(); 3079abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai memset(context.get(), 0, sizeof(MDRawContextX86)); 308ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai#endif /* TARGET_CPU_XXX */ 3099abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return WriteContext(context.get(), (int *)gregs, &fp_regs); 3109abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 3119abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 312dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteCPUInformation(MDRawSystemInfo *sys_info) { 3139abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai struct utsname uts; 3149abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai char *major, *minor, *build; 3159abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 3169abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai sys_info->number_of_processors = sysconf(_SC_NPROCESSORS_CONF); 3179abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai sys_info->processor_architecture = MD_CPU_ARCHITECTURE_UNKNOWN; 3189abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (uname(&uts) != -1) { 3199abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai // Match "i86pc" as X86 architecture. 3209abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (strcmp(uts.machine, "i86pc") == 0) 3219abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai sys_info->processor_architecture = MD_CPU_ARCHITECTURE_X86; 3229abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai else if (strcmp(uts.machine, "sun4u") == 0) 3239abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai sys_info->processor_architecture = MD_CPU_ARCHITECTURE_SPARC; 3249abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 3259abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 3269abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai major = uts.release; 3279abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai minor = strchr(major, '.'); 3289abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai *minor = '\0'; 3299abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai ++minor; 3309abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai sys_info->major_version = atoi(major); 3319abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai sys_info->minor_version = atoi(minor); 3329abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 3339abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai build = strchr(uts.version, '_'); 3349abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai ++build; 3359abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai sys_info->build_number = atoi(build); 3369abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 3379abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return true; 3389abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 3399abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 340dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteOSInformation(MinidumpFileWriter *minidump_writer, 341dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDRawSystemInfo *sys_info) { 3429abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai sys_info->platform_id = MD_OS_SOLARIS; 3439abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 3449abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai struct utsname uts; 3459abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (uname(&uts) != -1) { 3469abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai char os_version[512]; 3479abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai size_t space_left = sizeof(os_version); 3489abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai memset(os_version, 0, space_left); 3499abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai const char *os_info_table[] = { 3509abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai uts.sysname, 3519abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai uts.release, 3529abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai uts.version, 3539abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai uts.machine, 3549abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai "OpenSolaris", 3559abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai NULL 3569abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai }; 3579abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai for (const char **cur_os_info = os_info_table; 3589abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai *cur_os_info != NULL; 3599abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai ++cur_os_info) { 3609abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (cur_os_info != os_info_table && space_left > 1) { 3619abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai strcat(os_version, " "); 3629abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai --space_left; 3639abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 3649abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (space_left > strlen(*cur_os_info)) { 3659abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai strcat(os_version, *cur_os_info); 3669abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai space_left -= strlen(*cur_os_info); 3679abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } else { 3689abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai break; 3699abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 3709abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 3719abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 3729abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai MDLocationDescriptor location; 373dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!minidump_writer->WriteString(os_version, 0, &location)) 3749abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 3759abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai sys_info->csd_version_rva = location.rva; 3769abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 3779abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return true; 3789abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 3799abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 3809abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// Callback context for get writting lwp information. 3819abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovaistruct LwpInfoCallbackCtx { 382dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MinidumpFileWriter *minidump_writer; 383dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const WriterArgument *writer_args; 3849abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai TypedMDRVA<MDRawThreadList> *list; 3859abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai int lwp_index; 3869abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai}; 3879abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 3889abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovaibool LwpInformationCallback(lwpstatus_t *lsp, void *context) { 3899abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai bool success = true; 390dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek LwpInfoCallbackCtx *callback_context = 391dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek static_cast<LwpInfoCallbackCtx *>(context); 392dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 393dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // The current lwp is the one to handle the crash. Ignore it. 3949abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (lsp->pr_lwpid != pthread_self()) { 3959abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai LwpInfoCallbackCtx *callback_context = 3969abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai static_cast<LwpInfoCallbackCtx *>(context); 3979abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai MDRawThread lwp; 3989abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai memset(&lwp, 0, sizeof(MDRawThread)); 3999abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 400dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (lsp->pr_lwpid != callback_context->writer_args->crashed_lwpid || 401dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek callback_context->writer_args->sig_ctx == NULL) { 402dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek success = WriteLwpStream(callback_context->minidump_writer, 403dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek callback_context->writer_args->lwp_lister, 404dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek lsp, &lwp); 405dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } else { 406dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek success = WriteCrashedLwpStream(callback_context->minidump_writer, 407dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek callback_context->writer_args, 408dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek lsp, &lwp); 409dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } 4109abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (success) { 4119abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai callback_context->list->CopyIndexAfterObject( 4129abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai callback_context->lwp_index++, 4139abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai &lwp, sizeof(MDRawThread)); 4149abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 4159abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 4169abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 4179abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return success; 4189abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 4199abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 420dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteLwpListStream(MinidumpFileWriter *minidump_writer, 421dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const WriterArgument *writer_args, 422dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDRawDirectory *dir) { 4239abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai // Get the lwp information. 424dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const SolarisLwp *lwp_lister = writer_args->lwp_lister; 425dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int lwp_count = lwp_lister->GetLwpCount(); 4269abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (lwp_count < 0) 4279abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 428dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawThreadList> list(minidump_writer); 429ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!list.AllocateObjectAndArray(lwp_count - 1, sizeof(MDRawThread))) 4309abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 4319abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->stream_type = MD_THREAD_LIST_STREAM; 4329abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->location = list.location(); 433ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai list.get()->number_of_threads = lwp_count - 1; 4349abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 4359abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai LwpInfoCallbackCtx context; 436dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context.minidump_writer = minidump_writer; 437dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context.writer_args = writer_args; 4389abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context.list = &list; 4399abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context.lwp_index = 0; 4409abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai CallbackParam<LwpCallback> callback_param(LwpInformationCallback, 4419abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai &context); 4429abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai int written = 443dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek lwp_lister->Lwp_iter_all(lwp_lister->getpid(), &callback_param); 4449abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return written == lwp_count; 4459abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 4469abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 447dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteCVRecord(MinidumpFileWriter *minidump_writer, 448dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDRawModule *module, 449dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const char *module_path, 450dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek char *realname) { 451dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDCVInfoPDB70> cv(minidump_writer); 4529abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 4539abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai char path[PATH_MAX]; 4549abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai const char *module_name = module_path ? module_path : "<Unknown>"; 4559abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai snprintf(path, sizeof(path), "/proc/self/object/%s", module_name); 4569abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 457dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek size_t module_name_length = strlen(realname); 4586162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(uint8_t))) 4599abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 460dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!cv.CopyIndexAfterObject(0, realname, module_name_length)) 4619abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 4629abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 4639abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai module->cv_record = cv.location(); 4649abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai MDCVInfoPDB70 *cv_ptr = cv.get(); 4659abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai memset(cv_ptr, 0, sizeof(MDCVInfoPDB70)); 4669abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->cv_signature = MD_CVINFOPDB70_SIGNATURE; 4679abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->age = 0; 4689abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 4699abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai // Get the module identifier 4709abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai FileID file_id(path); 4719abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai unsigned char identifier[16]; 4729abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 4739abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (file_id.ElfFileIdentifier(identifier)) { 4749abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data1 = (uint32_t)identifier[0] << 24 | 4759abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai (uint32_t)identifier[1] << 16 | (uint32_t)identifier[2] << 8 | 4769abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai (uint32_t)identifier[3]; 4779abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data2 = (uint32_t)identifier[4] << 8 | identifier[5]; 4789abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data3 = (uint32_t)identifier[6] << 8 | identifier[7]; 4799abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data4[0] = identifier[8]; 4809abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data4[1] = identifier[9]; 4819abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data4[2] = identifier[10]; 4829abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data4[3] = identifier[11]; 4839abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data4[4] = identifier[12]; 4849abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data4[5] = identifier[13]; 4859abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data4[6] = identifier[14]; 4869abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai cv_ptr->signature.data4[7] = identifier[15]; 4879abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 4889abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return true; 4899abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 4909abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 4919abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovaistruct ModuleInfoCallbackCtx { 4929abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai MinidumpFileWriter *minidump_writer; 493dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const WriterArgument *writer_args; 4949abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai TypedMDRVA<MDRawModuleList> *list; 4959abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai int module_index; 4969abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai}; 4979abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 4989abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovaibool ModuleInfoCallback(const ModuleInfo &module_info, void *context) { 4999abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai ModuleInfoCallbackCtx *callback_context = 5009abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai static_cast<ModuleInfoCallbackCtx *>(context); 5019abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai // Skip those modules without name, or those that are not modules. 5029abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (strlen(module_info.name) == 0) 5039abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return true; 5049abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 5059abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai MDRawModule module; 5069abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai memset(&module, 0, sizeof(module)); 5079abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai MDLocationDescriptor loc; 508dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek char path[PATH_MAX]; 509dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek char buf[PATH_MAX]; 510dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek char *realname; 511dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int count; 512dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 513dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek snprintf(path, sizeof (path), "/proc/self/path/%s", module_info.name); 514dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if ((count = readlink(path, buf, PATH_MAX)) < 0) 515dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return false; 516dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek buf[count] = '\0'; 517dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 518dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if ((realname = strrchr(buf, '/')) == NULL) 519dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return false; 520dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek realname++; 521dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 522dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!callback_context->minidump_writer->WriteString(realname, 0, &loc)) 5239abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 5249abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 5256162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com module.base_of_image = (uint64_t)module_info.start_addr; 5269abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai module.size_of_image = module_info.size; 5279abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai module.module_name_rva = loc.rva; 5289abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 529dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!WriteCVRecord(callback_context->minidump_writer, &module, 530dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek module_info.name, realname)) 5319abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 5329abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 5339abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai callback_context->list->CopyIndexAfterObject( 5349abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai callback_context->module_index++, &module, MD_MODULE_SIZE); 5359abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return true; 5369abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 5379abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 538dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteModuleListStream(MinidumpFileWriter *minidump_writer, 539dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const WriterArgument *writer_args, 540dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDRawDirectory *dir) { 541dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawModuleList> list(minidump_writer); 542dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int module_count = writer_args->lwp_lister->GetModuleCount(); 5439abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 5449abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (module_count <= 0 || 5459abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai !list.AllocateObjectAndArray(module_count, MD_MODULE_SIZE)) { 5469abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 5479abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 5489abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 5499abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->stream_type = MD_MODULE_LIST_STREAM; 5509abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->location = list.location(); 5519abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai list.get()->number_of_modules = module_count; 5529abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai ModuleInfoCallbackCtx context; 553dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context.minidump_writer = minidump_writer; 554dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek context.writer_args = writer_args; 5559abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context.list = &list; 5569abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai context.module_index = 0; 5579abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai CallbackParam<ModuleCallback> callback(ModuleInfoCallback, &context); 558dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return writer_args->lwp_lister->ListModules(&callback) == module_count; 5599abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 5609abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 561dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteSystemInfoStream(MinidumpFileWriter *minidump_writer, 562dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const WriterArgument *writer_args, 563dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDRawDirectory *dir) { 564dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawSystemInfo> sys_info(minidump_writer); 5659abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 5669abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (!sys_info.Allocate()) 5679abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 5689abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 5699abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->stream_type = MD_SYSTEM_INFO_STREAM; 5709abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->location = sys_info.location(); 5719abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 5729abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return WriteCPUInformation(sys_info.get()) && 573dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek WriteOSInformation(minidump_writer, sys_info.get()); 5749abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 5759abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 576dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteExceptionStream(MinidumpFileWriter *minidump_writer, 577dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const WriterArgument *writer_args, 578dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDRawDirectory *dir) { 579dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // This happenes when this is not a crash, but a requested dump. 580dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (writer_args->sig_ctx == NULL) 5819abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 5829abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 583dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawExceptionStream> exception(minidump_writer); 5849abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (!exception.Allocate()) 5859abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 5869abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 5879abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->stream_type = MD_EXCEPTION_STREAM; 5889abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->location = exception.location(); 589dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek exception.get()->thread_id = writer_args->crashed_lwpid; 590dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek exception.get()->exception_record.exception_code = writer_args->signo; 5919abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai exception.get()->exception_record.exception_flags = 0; 5929abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 593ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai#if TARGET_CPU_SPARC 594dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (writer_args->sig_ctx != NULL) { 595dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek exception.get()->exception_record.exception_address = 596dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->sig_ctx->uc_mcontext.gregs[REG_PC]; 597dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } else { 598dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return true; 599dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } 600dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 601ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai // Write context of the exception. 602dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawContextSPARC> context(minidump_writer); 603ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai if (!context.Allocate()) 604ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai return false; 605ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai exception.get()->thread_context = context.location(); 606ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai memset(context.get(), 0, sizeof(MDRawContextSPARC)); 607dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return WriteContext(context.get(), writer_args->sig_ctx); 608ea2bba970675e01f9964f82d3f44960c1aad05dcmmentovai#elif TARGET_CPU_X86 609dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (writer_args->sig_ctx != NULL) { 610dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek exception.get()->exception_record.exception_address = 611dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->sig_ctx->uc_mcontext.gregs[EIP]; 612dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } else { 613dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return true; 614dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } 615dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 6169abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai // Write context of the exception. 617dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawContextX86> context(minidump_writer); 6189abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (!context.Allocate()) 6199abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 6209abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai exception.get()->thread_context = context.location(); 6219abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai memset(context.get(), 0, sizeof(MDRawContextX86)); 622dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return WriteContext(context.get(), 623dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek (int *)&writer_args->sig_ctx->uc_mcontext.gregs, 624dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek NULL); 625dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#endif 6269abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 6279abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 628dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteMiscInfoStream(MinidumpFileWriter *minidump_writer, 629dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const WriterArgument *writer_args, 630dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDRawDirectory *dir) { 631dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawMiscInfo> info(minidump_writer); 6329abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 6339abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (!info.Allocate()) 6349abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 6359abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 6369abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->stream_type = MD_MISC_INFO_STREAM; 6379abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->location = info.location(); 6389abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai info.get()->size_of_info = sizeof(MDRawMiscInfo); 6399abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai info.get()->flags1 = MD_MISCINFO_FLAGS1_PROCESS_ID; 640dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek info.get()->process_id = writer_args->requester_pid; 6419abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 6429abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return true; 6439abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 6449abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 645dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekbool WriteBreakpadInfoStream(MinidumpFileWriter *minidump_writer, 646dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const WriterArgument *writer_args, 647dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDRawDirectory *dir) { 648dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawBreakpadInfo> info(minidump_writer); 6499abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 6509abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (!info.Allocate()) 6519abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 6529abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 6539abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->stream_type = MD_BREAKPAD_INFO_STREAM; 6549abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir->location = info.location(); 6559abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 6569abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai info.get()->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID | 6579abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID; 6589abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai info.get()->dump_thread_id = getpid(); 659dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek info.get()->requesting_thread_id = writer_args->requester_pid; 6609abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return true; 6619abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 6629abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 6639abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovaiclass AutoLwpResumer { 6649abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai public: 6659abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai AutoLwpResumer(SolarisLwp *lwp) : lwp_(lwp) {} 6669abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai ~AutoLwpResumer() { lwp_->ControlAllLwps(false); } 6679abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai private: 6689abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai SolarisLwp *lwp_; 6699abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai}; 6709abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 671dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// Prototype of writer functions. 672dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarektypedef bool (*WriteStreamFN)(MinidumpFileWriter *, 673dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek const WriterArgument *, 674dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MDRawDirectory *); 675dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 676dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek// Function table to writer a full minidump. 677dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekconst WriteStreamFN writers[] = { 678dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek WriteLwpListStream, 679dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek WriteModuleListStream, 680dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek WriteSystemInfoStream, 681dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek WriteExceptionStream, 682dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek WriteMiscInfoStream, 683dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek WriteBreakpadInfoStream, 684dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek}; 685dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 6869abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// Will call each writer function in the writers table. 687dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek//void* MinidumpGenerator::Write(void *argument) { 688dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekvoid* Write(void *argument) { 689dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek WriterArgument *writer_args = static_cast<WriterArgument *>(argument); 690dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 691dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (!writer_args->lwp_lister->ControlAllLwps(true)) 6929abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return NULL; 6939abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 694dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek AutoLwpResumer lwpResumer(writer_args->lwp_lister); 695dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 696dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (writer_args->sighandler_ebp != 0 && 697dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->lwp_lister->FindSigContext(writer_args->sighandler_ebp, 698dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek &writer_args->sig_ctx)) { 699dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->crashed_stack_bottom = 700dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->lwp_lister->GetLwpStackBottom( 701dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#if TARGET_CPU_SPARC 702dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->sig_ctx->uc_mcontext.gregs[REG_O6] 703dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#elif TARGET_CPU_X86 704dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->sig_ctx->uc_mcontext.gregs[UESP] 705dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek#endif 706dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek ); 707dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 708dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int crashed_lwpid = FindCrashingLwp(writer_args->crashed_stack_bottom, 709dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->requester_pid, 710dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->lwp_lister); 711dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (crashed_lwpid > 0) 712dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek writer_args->crashed_lwpid = crashed_lwpid; 713dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek } 7149abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 715dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MinidumpFileWriter *minidump_writer = writer_args->minidump_writer; 716dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawHeader> header(minidump_writer); 717dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek TypedMDRVA<MDRawDirectory> dir(minidump_writer); 7189abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (!header.Allocate()) 7199abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return 0; 7209abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 7219abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai int writer_count = sizeof(writers) / sizeof(writers[0]); 7229abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai // Need directory space for all writers. 7239abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (!dir.AllocateArray(writer_count)) 7249abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return 0; 7259abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai header.get()->signature = MD_HEADER_SIGNATURE; 7269abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai header.get()->version = MD_HEADER_VERSION; 7279abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai header.get()->time_date_stamp = time(NULL); 7289abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai header.get()->stream_count = writer_count; 7299abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai header.get()->stream_directory_rva = dir.position(); 7309abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 7319abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai int dir_index = 0; 7329abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai MDRawDirectory local_dir; 7339abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai for (int i = 0; i < writer_count; ++i) { 734dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if ((*writers[i])(minidump_writer, writer_args, &local_dir)) 7359abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai dir.CopyIndex(dir_index++, &local_dir); 7369abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 7379abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 7389abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return 0; 7399abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 7409abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 741dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek} // namespace 742dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 743dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczareknamespace google_breakpad { 744dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 745dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekMinidumpGenerator::MinidumpGenerator() { 746dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek} 747dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 748dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarekMinidumpGenerator::~MinidumpGenerator() { 749dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek} 750dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 7519abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// Write minidump into file. 7529abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai// It runs in a different thread from the crashing thread. 7539abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovaibool MinidumpGenerator::WriteMinidumpToFile(const char *file_pathname, 754dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek int signo, 755dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek uintptr_t sighandler_ebp, 756dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek ucontext_t **sig_ctx) const { 757dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek // The exception handler thread. 758dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek pthread_t handler_thread; 759dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 7609abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai assert(file_pathname != NULL); 7619abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 7629abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai if (file_pathname == NULL) 7639abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 7649abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 765dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek MinidumpFileWriter minidump_writer; 766dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek if (minidump_writer.Open(file_pathname)) { 767dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek WriterArgument argument; 768dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek memset(&argument, 0, sizeof(argument)); 7699abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai SolarisLwp lwp_lister(getpid()); 770dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek argument.lwp_lister = &lwp_lister; 771dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek argument.minidump_writer = &minidump_writer; 772dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek argument.requester_pid = getpid(); 773dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek argument.crashed_lwpid = pthread_self(); 774dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek argument.signo = signo; 775dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek argument.sighandler_ebp = sighandler_ebp; 776dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek argument.sig_ctx = NULL; 777dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek 778dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek pthread_create(&handler_thread, NULL, Write, (void *)&argument); 779dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek pthread_join(handler_thread, NULL); 780dd2ff4a21c57672170eb14ccc5142efd7d92f3f1ted.mielczarek return true; 7819abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai } 7829abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 7839abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai return false; 7849abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} 7859abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai 7869abfe3d0a5bbefd85c54feda0dac2d030cbb5635mmentovai} // namespace google_breakpad 787