I run into an interesting problem with linuxemu.
The problem *seems* to be that traps can be
enqueued in the process note array *after* some
other note causing notify() to kill us.
Please correct me if i miss(understand) something
here. It just hit my mind after hours of late night
debugging.
The case:
If some other process sends a note with postnote(). The
kernel will enqueue the note in the target process.
(The note is marked as Nuser)
notestate of the target process:
note[0] = {Nuser, "usernote"}
nnote = 1
notified = 0
This note will be "delivered" when notify() is called.
notify is called on:
- after a syscall
- after interrupt/trap handling (timer interrupt?)
Now, in our case, the receiving process causes a trap.
It enters the kernel from the vector table
and /sys/src/9/pc/trap.c:trap() is called.
trap() decodes the error and enqueues a note
with the Ndebug flag.
the target process note state now looks like
this:
note[0] = {Nuser, "usernote"}
note[1] = {Ndebug, "sys: trap: some trap"}
nnote = 2
notified = 0
trap() now calls notify() because nnote != 0.
notify() delivers the "usernote" and sets
notified = 1;
we return to userspace with kexit() and we
pop out in the note handler to process the
"usernote".
the note state looks now like this:
note[0] = {Ndebug, "sys: trap: some trap"}
nnote = 1
notified = 1
now strange things happen. if we enter
the kernel for some reason (syscall, timer
interrupt?)
notify() will kill us:
/* n is the address of the 0th entry from the note array */
if(n->flag!=NUser && (up->notified || up->notify==0)){
if(n->flag == NDebug)
pprint("suicide: %s\n", n->msg);
qunlock(&up->debug);
pexit(n->msg, n->flag!=NDebug);
}
if we are lucky, we could do a noted() inside
the notehandler and it will set up->notified to
zero before some the timer interrupt arrives.
What i need is that i get the Ndebug-note in the
notehandler *first*. it doesnt make sense to me to
queue traps.
Something similar i found in postnote():
if(flag != NUser && (p->notify == 0 || p->notified))
p->nnote = 0;
but obviously this only works if it has already notified
the process. why?
--
cinap