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

Signal handling question



I am porting some code to the Debian Sparc platform. I have encountered a
problem, and since I believe my code is doing everything correctly, I
wondered if it was a problem with the kernel?

I suspect the precise version of my kernel isn't important for this
problem, but for completeness here's what dmesg says:
  Linux version 2.4.18 (root@vore) (gcc version egcs-2.92.11 19980921
  (gcc2 ss-980609 experimental)) #2 Thu Apr 11 14:37:17 EDT 2002

I am trying to install a signal handler. The handler needs to know the
address that caused the exception and whether it was a read or write. So
I install the handler like this:

   {
     struct sigaction act;
     act.sa_sigaction = myhandler;
     act.sa_flags = SA_SIGINFO;

     sigaction(SIGSEGV, &act, NULL);
   }

I use the SA_SIGINFO flag so that my handler is passed the structures I
need to work out the address etc.

Unfortunately to work out whether it was a read or write I need to
disassemble the instruction that made the access. This is because the
information structure passed to my handler doesn't say whether it was a
read or write access (BTW, it does on other platforms).

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. The documentation I have read
suggests it should point to a (large) structure containing the information
I require to calculate the PC.

So I had a look at arch/sparc64/kernel/signal.c. As far as I can tell, it
doesn't have code to set this third argument. Should it do this? I found
the following code:

	/* 3. signal handler back-trampoline and parameters */
	regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS;
	regs->u_regs[UREG_I0] = signo;
	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;

But as you can see, only the first two arguments are set?

By the way, my program is multithreaded, but I install the signal handler
before spawning any threads, so it should be alright, right?

James.

PS. I was originally going to send this question to the kernel specific
list mentioned on http://www.debian.org/ports/sparc/. It says "Kernel
questions should be addressed to the list <sparclinux@vger.rutgers.edu>.
Subscribe by sending a message with body `subscribe sparclinux' to the
address majordomo@vger.rutgers.edu." Unfortunately the
majordomo@vger.rutgers.edu address is not valid. I think the web page
needs updating.


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



Reply to: