On 05/15/2010 02:15 PM, Christophe Rhodes wrote:
Valentin Pavlov <x.pavlov@gmail.com> writes:

  
OK, here it goes a [not so-] short story:
    
Great stuff.
  
I appreciate that you appreciate it ;-))
  
  - in a signal handler, when you make changes to the context (e.g.
arch_skip_next_instruction) nothing happens. It turns out that the context
you get passed is a read-only copy, and the real thing that gets copied back
to the caller before sigreturn is further down the stack. Moreover, due to
cache lineup, it is not on a fixed offset from SP, so I have to first find
it. Thus, a wrapper around the signal handlers (e.g. SIGTRAP, SIGSEGV, etc.)
first finds the offset of the real context (I named it Amber after Zelazny's
novels), and then before returning copies the contents of the context to
Amber. The sigreturn then copies the modifed Amber context to the caller.
Suddenly, the runtime started to execute cold-sbcl.core and all was ok,
until the first garbage collection when all hell broke (lose);
    
This reminds me of the problem with SPARC/Linux, way back when: again,
the context was somewhere on the stack (at a constant offset, in my
case), and what was in the third argument to the signal handler was not
documented and not useful.  That's why there's the slightly weird
arch_os_get_context() call, where you could hook in your search for the
context.

  
Well, I first tried that. But then realized it won't work. In order to find where the true context is, I memcmp the 32 GPRGs from the os context starting at a given address offset (I do this max 8 times). If I change the value of a register in one of the contexts, they won't match anymore. So I had to make changes in both. And since arch_os_get_context is called on several occasions, I decided that it would be more beneficial to first find it, store its address, then work with the false context as usual, and then at the end transfer all registers. 

cheers,
-Valentin