mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-01-01 20:24:40 +01:00
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
This commit is contained in:
parent
278946c3b5
commit
ea2bba9706
17 changed files with 1044 additions and 40 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue