[Mono-list] Nasty x86_magic_trampoline gremlin: ambiguous call sequences

Paolo Molaro lupus@ximian.com
Sun, 24 Feb 2002 18:24:05 +0100

On 02/24/02 Eric Kidd wrote:
> On Sun, 2002-02-24 at 08:04, Paolo Molaro wrote:
> > Funnyly enough I found this bug this morning, too, while adding
> > support for tracking a few statistics in the JIT. At the fifth counter
> > I added, it started segfaulting...
> > Your test program works for me after the fix (but it did work before
> > that, too). My fix is in cvs now, let me know if it works for you.
> -       if ((code [3] == 0xff) && ((code [4] & 0x18) == 0x10) && ((code [4] >> 6) == 1)) {
> +       if ((code [1] != 0xe8) && (code [3] == 0xff) && ((code [4] & 0x18) == 0x10) && ((code [4] >> 6) == 1)) {
> I'm not quite sure I understand this fix--does anything guarantee that
> the preceding instruction could *never* contain an 0xe8?  This code
> needs to work for 100% of legal instruction streams, not just 99.999%.
> I understand why 'ff MR ** ** ** **' and '.. e8 ** ** ** **' are always
> unambiguous, but I don't yet understand why a valid '.. .. .. ff MR **'
> could never appear as '.. e8 .. ff MR **'.
> Please help a poor novice JIT hacker find enlightenment. ;-)

It's basically the same reason why 'ff MR ** ff ** **' and
'.. .. .. ff MR **' in practice are unambiguos: the displacement
of a method in the vtable is small. It'd require a vtable with millions
of methods, but I'm sure you'd have other problems than this in that
This works because we always do a x86_mov_reg_membase() before the
virtual call and that can never generate that byte sequence, unless the
interface table is bigger than 0xe80000 bytes.
It may become a problem if we do some fancy instruction scheduling later, 
but in that case it would be better to use a different trampoline for
methods called with the '0xe8 imm32' opcode. Dietmar might explain
better why he changed the code to use the same trampoline.

> P.S.  The patched version now segfaults in a different place for me. 

Same sample code?

> What's the recommended way for debugging JIT'd code?

There is some support to write out stab information that you can later
load in gdb: it's not complete and it has the limitation of the stab
format, but it may be useful. A brief doc explains how to use it in
mono/docs/jit-debug. It's more useful if the jit can compile all the
methods of a class you need to debug.
I plan to output dwarf-2 debug info sometime in the future, but any help
here is appreciated.


lupus@debian.org                                     debian/rules
lupus@ximian.com                             Monkeys do it better