diff options
author | mmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2007-09-26 18:28:05 +0000 |
---|---|---|
committer | mmentovai <mmentovai@4c0a9323-5329-0410-9bdc-e9ce6186880e> | 2007-09-26 18:28:05 +0000 |
commit | ea2bba970675e01f9964f82d3f44960c1aad05dc (patch) | |
tree | d3d6744bf2ef136f9a89748c96ab4e5c465eb7ff /src/client | |
parent | Fix crash reason switching to allow proper behavior for Linux. Spotted by (diff) | |
download | breakpad-ea2bba970675e01f9964f82d3f44960c1aad05dc.tar.xz |
Add SPARC/Solaris support to client handler and processor (#201, 200).
Patch by Michael shang <satisfy123>. r=me, r=Alfred Peng.
http://groups.google.com/group/google-breakpad-discuss/browse_thread/thread/2fba07577f1fa35e
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@215 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client')
-rw-r--r-- | src/client/solaris/handler/Makefile | 3 | ||||
-rw-r--r-- | src/client/solaris/handler/minidump_generator.cc | 83 | ||||
-rw-r--r-- | src/client/solaris/handler/minidump_generator.h | 13 | ||||
-rw-r--r-- | src/client/solaris/handler/solaris_lwp.cc | 20 |
4 files changed, 101 insertions, 18 deletions
diff --git a/src/client/solaris/handler/Makefile b/src/client/solaris/handler/Makefile index 425d66f2..318ac8e5 100644 --- a/src/client/solaris/handler/Makefile +++ b/src/client/solaris/handler/Makefile @@ -73,4 +73,5 @@ $(BIN_DIR)/exception_handler_test:$(EXCEPTION_TEST_OBJ) $(CXX) $(CPPFLAGS) $(LDFLAGS) $^ -o $@ clean: - rm -f $(BIN) *.o *.out *.dmp core + rm -f $(BIN) *.o *.out *.dmp core ../../minidump_file_writer.o\ + ../../../common/*.o ../../../common/solaris/*.o diff --git a/src/client/solaris/handler/minidump_generator.cc b/src/client/solaris/handler/minidump_generator.cc index bcb9d88b..f86e2df1 100644 --- a/src/client/solaris/handler/minidump_generator.cc +++ b/src/client/solaris/handler/minidump_generator.cc @@ -60,7 +60,7 @@ bool MinidumpGenerator::WriteLwpStack(uintptr_t last_esp, UntypedMDRVA *memory, MDMemoryDescriptor *loc) { uintptr_t stack_bottom = lwp_lister_->GetLwpStackBottom(last_esp); - if (stack_bottom > last_esp) { + if (stack_bottom >= last_esp) { int size = stack_bottom - last_esp; if (size > 0) { if (!memory->Allocate(size)) @@ -74,6 +74,28 @@ bool MinidumpGenerator::WriteLwpStack(uintptr_t last_esp, return false; } +#if TARGET_CPU_SPARC +bool MinidumpGenerator::WriteContext(MDRawContextSPARC *context, prgregset_t regs, + prfpregset_t *fp_regs) { + if (!context || !regs) + return false; + + context->context_flags = MD_CONTEXT_SPARC_FULL; + + context->ccr = (unsigned int)(regs[32]); + context->pc = (unsigned int)(regs[R_PC]); + context->npc = (unsigned int)(regs[R_nPC]); + context->y = (unsigned int)(regs[R_Y]); + context->asi = (unsigned int)(regs[36]); + context->fprs = (unsigned int)(regs[37]); + + for ( int i = 0 ; i < 32 ; ++i ){ + context->g_r[i] = (unsigned int)(regs[i]); + } + + return true; +} +#elif TARGET_CPU_X86 bool MinidumpGenerator::WriteContext(MDRawContextX86 *context, prgregset_t regs, prfpregset_t *fp_regs) { if (!context || !regs) @@ -100,23 +122,41 @@ bool MinidumpGenerator::WriteContext(MDRawContextX86 *context, prgregset_t regs, return true; } +#endif /* TARGET_CPU_XXX */ bool MinidumpGenerator::WriteLwpStream(lwpstatus_t *lsp, MDRawThread *lwp) { prfpregset_t fp_regs = lsp->pr_fpreg; prgregset_t *gregs = &(lsp->pr_reg); UntypedMDRVA memory(&writer_); - if (!WriteLwpStack((*gregs)[UESP], +#if TARGET_CPU_SPARC + if (!WriteLwpStack((*gregs)[R_SP], &memory, &lwp->stack)) return false; // Write context + TypedMDRVA<MDRawContextSPARC> context(&writer_); + if (!context.Allocate()) + return false; + // should be the thread_id + lwp->thread_id = lsp->pr_lwpid; + lwp->thread_context = context.location(); + memset(context.get(), 0, sizeof(MDRawContextSPARC)); +#elif TARGET_CPU_X86 + if (!WriteLwpStack((*gregs)[UESP], + &memory, + &lwp->stack)) + return false; + + // Write context TypedMDRVA<MDRawContextX86> context(&writer_); if (!context.Allocate()) return false; - lwp->thread_id = lwp_lister_->getpid(); + // should be the thread_id + lwp->thread_id = lsp->pr_lwpid; lwp->thread_context = context.location(); memset(context.get(), 0, sizeof(MDRawContextX86)); +#endif /* TARGET_CPU_XXX */ return WriteContext(context.get(), (int *)gregs, &fp_regs); } @@ -220,11 +260,11 @@ bool MinidumpGenerator::WriteLwpListStream(MDRawDirectory *dir) { if (lwp_count < 0) return false; TypedMDRVA<MDRawThreadList> list(&writer_); - if (!list.AllocateObjectAndArray(lwp_count, sizeof(MDRawThread))) + if (!list.AllocateObjectAndArray(lwp_count - 1, sizeof(MDRawThread))) return false; dir->stream_type = MD_THREAD_LIST_STREAM; dir->location = list.location(); - list.get()->number_of_threads = lwp_count; + list.get()->number_of_threads = lwp_count - 1; LwpInfoCallbackCtx context; context.generator = this; @@ -351,8 +391,8 @@ bool MinidumpGenerator::WriteSystemInfoStream(MDRawDirectory *dir) { bool MinidumpGenerator::WriteExceptionStream(MDRawDirectory *dir) { ucontext_t uc; - prgregset_t *gregs; - prfpregset_t fp_regs; + gregset_t *gregs; + fpregset_t fp_regs; if (getcontext(&uc) != 0) return false; @@ -369,8 +409,34 @@ bool MinidumpGenerator::WriteExceptionStream(MDRawDirectory *dir) { gregs = &(uc.uc_mcontext.gregs); fp_regs = uc.uc_mcontext.fpregs; +#if TARGET_CPU_SPARC + exception.get()->exception_record.exception_address = ((unsigned int *)gregs)[1]; + // Write context of the exception. + TypedMDRVA<MDRawContextSPARC> context(&writer_); + if (!context.Allocate()) + return false; + exception.get()->thread_context = context.location(); + memset(context.get(), 0, sizeof(MDRawContextSPARC)); + + // On Solaris i386, gregset_t = prgregset_t, fpregset_t = prfpregset_t + // But on Solaris Sparc are diffrent, see sys/regset.h and sys/procfs_isa.h + context.get()->context_flags = MD_CONTEXT_SPARC_FULL; + context.get()->ccr = ((unsigned int *)gregs)[0]; + context.get()->pc = ((unsigned int *)gregs)[1]; + context.get()->npc = ((unsigned int *)gregs)[2]; + context.get()->y = ((unsigned int *)gregs)[3]; + context.get()->asi = ((unsigned int *)gregs)[19]; + context.get()->fprs = ((unsigned int *)gregs)[20]; + for (int i = 0; i < 32; ++i) { + context.get()->g_r[i] = 0; + } + for (int i = 1; i < 16; ++i) { + context.get()->g_r[i] = ((unsigned int *)gregs)[i + 3]; + } + + return true; +#elif TARGET_CPU_X86 exception.get()->exception_record.exception_address = (*gregs)[EIP]; - // Write context of the exception. TypedMDRVA<MDRawContextX86> context(&writer_); if (!context.Allocate()) @@ -378,6 +444,7 @@ bool MinidumpGenerator::WriteExceptionStream(MDRawDirectory *dir) { exception.get()->thread_context = context.location(); memset(context.get(), 0, sizeof(MDRawContextX86)); return WriteContext(context.get(), (int *)gregs, &fp_regs); +#endif /* TARGET_CPU_XXX */ } bool MinidumpGenerator::WriteMiscInfoStream(MDRawDirectory *dir) { diff --git a/src/client/solaris/handler/minidump_generator.h b/src/client/solaris/handler/minidump_generator.h index 36b92716..82309936 100644 --- a/src/client/solaris/handler/minidump_generator.h +++ b/src/client/solaris/handler/minidump_generator.h @@ -32,6 +32,14 @@ #ifndef CLIENT_SOLARIS_HANDLER_MINIDUMP_GENERATOR_H__ #define CLIENT_SOLARIS_HANDLER_MINIDUMP_GENERATOR_H__ +#if defined(sparc) || defined(__sparc__) +#define TARGET_CPU_SPARC 1 +#elif defined(i386) || defined(__i386__) +#define TARGET_CPU_X86 1 +#else +#error "cannot determine cpu type" +#endif + #include "client/minidump_file_writer.h" #include "client/solaris/handler/solaris_lwp.h" #include "google_breakpad/common/breakpad_types.h" @@ -69,8 +77,13 @@ class MinidumpGenerator { MDMemoryDescriptor *loc); // Write CPU context based on provided registers. +#if TARGET_CPU_SPARC + bool WriteContext(MDRawContextSPARC *context, prgregset_t regs, + prfpregset_t *fp_regs); +#elif TARGET_CPU_X86 bool WriteContext(MDRawContextX86 *context, prgregset_t regs, prfpregset_t *fp_regs); +#endif /* TARGET_CPU_XXX */ // Write information about a lwp. // Only processes lwp running normally at the crash. diff --git a/src/client/solaris/handler/solaris_lwp.cc b/src/client/solaris/handler/solaris_lwp.cc index 763e1977..9ce7b4fd 100644 --- a/src/client/solaris/handler/solaris_lwp.cc +++ b/src/client/solaris/handler/solaris_lwp.cc @@ -217,7 +217,7 @@ int SolarisLwp::Lwp_iter_all(int pid, lwpsinfo_t *Lpsp; long nstat; long ninfo; - int rv; + int rv = 0; /* * The /proc/pid/lstatus file has the array of lwpstatus_t's and the @@ -240,8 +240,9 @@ int SolarisLwp::Lwp_iter_all(int pid, sp = NULL; } if (callback_param && - !(rv = (callback_param->call_back)(sp, callback_param->context))) + !(callback_param->call_back)(sp, callback_param->context)) break; + ++rv; Lpsp = (lwpsinfo_t *)((uintptr_t)Lpsp + Lphp->pr_entsize); } @@ -279,7 +280,8 @@ int SolarisLwp::ListModules( return -1; /* - * Determine number of mappings. + * Determine number of mappings, this value must be + * larger than the actual module count */ size = status.st_size; if ((num = (int)(size / sizeof (prmap_t))) > MAP_MAX) { @@ -287,9 +289,6 @@ int SolarisLwp::ListModules( return -1; } - if (!callback_param) - return num; // return the Module count - if (read(fd, (void *)maps, size) < 0) { print_message2(2, "failed to read %d\n", fd); return -1; @@ -297,7 +296,8 @@ int SolarisLwp::ListModules( prmap_t *_maps; int _num; - + int module_count = 0; + /* * Scan each mapping - note it is assummed that the mappings are * presented in order. We fill holes between mappings. On intel @@ -313,15 +313,17 @@ int SolarisLwp::ListModules( memset(&module, 0, sizeof (module)); module.start_addr = _maps->pr_vaddr; module.size = _maps->pr_size; - if (name && (strcmp(name, "a.out") != 0)) + if ((strlen(name) > 0) && (strcmp(name, "a.out") != 0)) { strncpy(module.name, name, sizeof (module.name) - 1); + ++module_count; + } if (callback_param && (!callback_param->call_back(module, callback_param->context))) { break; } } - return num; + return module_count; } } // namespace google_breakpad |