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 |