[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Signal handling question



James Green <jng@globespanvirata.com> writes:

> So my handler begins like this:
> 
> static void myhandler(int signum, siginfo_t* info, void *pContext)
> {
>   unsigned int fault_address = (unsigned int)(info->si_addr);
>   unsigned int iswrite = 0;
> 
>   {
>     /* Determine whether this was a read or write by disassembling the
>        faulting instruction. */
>     ucontext_t* context = (ucontext_t*)pContext;
>     greg_t pc = (context->uc_mcontext).gregs[REG_PC];
>     .....
> 
> The fault_address address variable that I calculate seems to be
> approximately correct. I haven't checked it out fully yet, because
> there are bigger problems, namely pContext the third
> argument. pContext never seems to contain a sensible pointer.

That's fixed since 2.4.19-pre<something>.  Note that the third
argument isn't a ucontext_t* on sparc/sparc64, it's a sigcontext* (see
/usr/include/bits/sigcontext.h, this is the same as pt_regs in
kernel).

In order to get the sigcontext on 2.4.18 or older you can use
something like this:

,----
| struct pt_regs {
|         unsigned long psr;
|         unsigned long pc;
|         unsigned long npc;
|         unsigned long y;
|         unsigned long u_regs[16]; /* globals and ins */
| };
| 
| /* A Sparc stack frame */
| struct sparc_stackf {
|         unsigned long locals[8];
|         unsigned long ins[6];
|         struct sparc_stackf *fp;
|         unsigned long callers_pc;
|         char *structptr;
|         unsigned long xargs[6];
|         unsigned long xxargs[1];
| };      
| 
| struct rt_signal_frame {
|   struct sparc_stackf    ss;
|   siginfo_t              info;
|   struct pt_regs         regs;
|   sigset_t               mask;
|   void                  *fpu_save;
|   unsigned int           insns [2];
|   stack_t                stack;
| #if 0
|   unsigned int            extra_size; /* Should be 0 */
|   __siginfo_fpu_t         fpu_state;
| #endif
| };
| 
| #define STACKFRAME_SZ sizeof(struct sparc_stackf)
| 
| static void myhandler(int signum, siginfo_t* info, void *pContext)
| {
|   /* ignore pContext */
|   pt_regs* regs = 
|     &((struct rt_signal_frame*) ((char*) info - STACKFRAME_SZ))->regs;
|   unsigned long pc = regs->pc;
| ...
`----


        Juergen

-- 
Juergen Kreileder, Blackdown Java-Linux Team
http://www.blackdown.org/java-linux.html


-- 
To UNSUBSCRIBE, email to debian-sparc-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org



Reply to: