site_archiver@lists.apple.com Delivered-To: darwin-dev@lists.apple.com What is GP2? Is this the EIP in the saved registers or the faultvaddr? Do you mean getcontext (man ucontext)? According to the sigaction manpage, the handler has this interface so the user context (thread state?) is given. -- Terry _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-dev mailing list (Darwin-dev@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-dev/site_archiver%40lists.appl... On Jan 19, 2009, at 2:51 PM, Joel Reymont wrote: On Jan 19, 2009, at 10:35 PM, Terry Lambert wrote: The GP2 does not get the faulting address on i385 if it is in the 64 bit hole. Otherwise it is the faulting address. I need to get hold of the return EIP, I think, i.e. the address I will be going back to. There are five types of memory faults that result in an exception. The first type is a memory fault for a a page which is mapped; these include trying to write to a page which is mapped read-only or read/ execute. The second type is attempting to execute in a page that isn't marked executable. The third is attempting to read a page which is not marked readable. The fourth is attempting to read/write/ execute a page which simply isn't mapped. The final type is attempting to access for any reason a page which is in the architectural address space hole which is the difference between the architected 64 bit address space and the implemented 48 bit address space on current CPUs. This last one turns into a General Protection Fault, and it's a different once than the others in that it is impossible to get back the address resulting in the fault because the bits are simply not available from the processor at the time the fault occurs. The only way you're getting those bits back is if you do instruction stream emulation by knowing where you should have been executing at the time of the failure, and emulate it to the point of saying "yes this is the emulated faulting address". The other types of exception that you end up with are divided into data access exceptions (which translate out as SIGBUS and SIGSEGV) or an instruction access exception (which mostly translates into a SIGILL, unless you've used floating point). Assuming you didn't general protection yourself, by the time this gets to your signal handler, half of the information has been lost, however, since we cache the si_addr value at exception time, and based on the exception type, we have to pick whether it means the address of the faulting instruction (which it will be, for a SIGILL or SIGFPE), or the address of the faulting memory reference (which it will be for a SIGSEGV pr SIGBUS). So basically, you are going to lose the information you want when using signals to do this sort of thing, even if you do manage to cast the third argument out of a void * (which it is) and dig it out of the right out of several ucontext_t structures which might be being used (depending on the architecture and the age of the binary). Don't expect siginfo to not change. Unless you are a debugger, and rev every time week rev the os, expect your code to break. A call to getthreadstate is a better bet. void handler(int, siginfo_t *info, ucontext_t *uap); It says that in the example. In the definition section, it's considered a void *, meaning "no user serviceable parts inside". This lets us change it if we need to, with the only thing being damaged by a change being gdb itself, since no one else is actually supposed to be looking at it. If you want to file a documentation bug vs. the BSD kernel component, I can get the example part of the man change pages to make sure it says "void *" there, too. What am I missing? There are actually a bunch of different ucontext formats. The ucontext format will generally be changed (or it's ID changed) when we release a new set of tools or a new version of the OS, or a new platform (which happens to require it). How to decode it is based on its ID, and that's subject to change. For example, the uc_mcontext field is a structure pointer or literal inlined data, depending. The context can be 32 bit, 64 bit, or both (which was needed to support 64 bit leaf functions on PPC64 code called from PPC32 code). There's really a lot of tricky, ugly stuff that happens in there, and you can't depend on it (you can only depend on us to update the tools we ship at the same time we ship the OS, if we've updated the OS between one release and the next). This email sent to site_archiver@lists.apple.com