|
From: Nicholas N. <nj...@ca...> - 2003-02-20 20:34:29
|
Hi,
I'm working on a skin that tracks how values were computed. One important
thing about this is that if an arch. register's value changes without the
skin's knowledge, things get inconsistent and it bombs out with assertion
failures.
I just discovered that signal delivery is one possible cause of this --
when a signal is delivered, %ESP is changed. Currently, a skin has no way
of knowing about this.
I propose adding an event so a skin can be told when signals are
delivered. In my working copy, I've added a new event:
void (*pre_deliver_signal) ( ThreadId tid, Int sigNo,
Bool alt_stack );
The calls to this were inserted at the top of vg_push_signal_frame(), one
in each branch if the first if-then-else (with different values of
'alt_stack'). I put in the 'alt_stack' parameter because I thought it
might be useful.
What do people think of this event? If everyone is happy, I will commit
it to the head.
----
A related question: can anyone think of any other ways in which a
register's value (or memory cell's value) could change like this without a
skin being aware of it? I'd just like to avoid having to work out any
further cases for myself :)
Thanks.
N
|
|
From: Julian S. <js...@ac...> - 2003-02-20 22:52:33
|
> What do people think of this event? If everyone is happy, I will commit > it to the head. Sounds pretty harmless to me ... commit, I say. > A related question: can anyone think of any other ways in which a > register's value (or memory cell's value) could change like this without a > skin being aware of it? I'd just like to avoid having to work out any > further cases for myself :) Values returned from client requests are placed in some reg (is it %EDX) ? I guess you must have this covered already. Ditto syscalls. make_thread_jump_to_cancelhdlr() -- part of the threading stuff -- messes with %ESP as well. It's pretty rare though. Hmm .. can't think of any others just now. J |
|
From: Nicholas N. <nj...@ca...> - 2003-02-21 10:32:19
|
On Thu, 20 Feb 2003, Julian Seward wrote:
> Sounds pretty harmless to me ... commit, I say.
Turns out I need a similar event for when the signal frame is popped. I
added:
void (*post_deliver_signal) ( ThreadId tid, Int sigNo );
which is called at the very end of vg_pop_signal_frame(). No 'alt_stack'
parameter this time, basically because it's not easily available. Any
skin that really needs to know it can cache the value from
pre_deliver_signal().
Interestingly, it seems that not only %esp but also %eax and %edx can be
trashed when a signal returns, although I couldn't find the code that
caused this.
I realised that for my skin's purposes, these new events weren't necessary
because the events new_mem_stack_signal() and die_mem_stack_signal() occur
at the same time... well, I need the ThreadId (so I can update
tst->sh_esp) which these events don't have. And pre/post_deliver_signal
seem like useful events to have in general. So if there are no further
objections I will commit them.
> > A related question: can anyone think of any other ways in which a
> > register's value (or memory cell's value) could change like this without a
> > skin being aware of it? I'd just like to avoid having to work out any
> > further cases for myself :)
>
> Values returned from client requests are placed in some reg (is it %EDX) ?
> I guess you must have this covered already. Ditto syscalls.
The shadows get set to VG_(written_value) by the core, which my skin
specifies as an "unknown" for which the values don't have to match. With
syscalls I overwrite this "unknown" value with something more informative
in VG_(post_syscall)().
> make_thread_jump_to_cancelhdlr() -- part of the threading stuff -- messes
> with %ESP as well. It's pretty rare though.
That's why it's useful to know -- saves me hunting it down in some large
program that dies after one million basic blocks :) Unfortunately, it's a
tricky case because again there's no way for a skin to know about this...
new_mem_stack isn't called because:
/* Push a bogus return address. It will not return, but we still
need to have it so that the arg is at the correct stack offset.
Don't mark as readable; any attempt to read this is and internal
valgrind bug since thread_exit_wrapper should not return. */
Hmm. There's a conflict of interest between skins here -- new_mem_stack
can be used to identify newly addressible memory, and it can also be used
to identify when %esp is changed. MemCheck/AddrCheck don't want
new_mem_stack to be called here, but my new skin does. Hmm.
Also, I again need the ThreadId, which new_mem_stack doesn't have anyway.
Looking elsewhere more carefully, %esp is fiddled with in
do__apply_in_new_thread too. That one's easier to spot because there is a
new_mem_stack call there, but still the lack of ThreadId is a problem.
Maybe I could just set every thread's sh_esp as unknown. Maybe I could
just tolerate occasional unexpected changes in %esp in my skin. Hmm.
N
|