|
From: Steve B. <Ste...@an...> - 2005-02-03 03:33:36
|
Hi Jeremy,
I don't know much about valgrind, but...
> Um, are you sure? I think the only interrupts which usable under Linux
> are int3 and int $0x80. int3 is the breakpoint instruction, and is a
> special case because it has a 1 byte opcode rather than 2 bytes.
In Jikes RVM we generate a number of software traps using the INT instruction.
These are int 40 through to int 43. We use these to catch conditions such as
array bounds violations, throw control to a signal handler which then starts our
(Java) execption handling mechanism. So, yes, we do use these, and we catch
them in a regular signal hanler.
> If you try to run any other interrupt, you just get a GPF, which looks
> like a SIGSEGV to user mode (currently we get this wrong by generating a
> SIGILL, but nothing cares).
OK. Perhaps this is right. Perhaps we just look at the culprit instruction and
use the fact that it was an int rather than a load/store to determine what
condition we're handling. We do nonetheless generate an int instruction....
Perhaps all that needs to be done is for valgrind to implemetn the behavior you
describe above: make it look like a SIGSEGV.
Cheers,
--Steve
==21231== Cachegrind, an I1/D1/L2 cache profiler for x86-linux.
==21231== Copyright (C) 2002-2004, and GNU GPL'd, by Nicholas Nethercote et al.
==21231== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==21231== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==21231== For more details, rerun with: -v
==21231==
disInstr: unhandled instruction bytes: 0xCC 0xDF 0x32 0x57
at 0x5732DF9C: ???
Just to give some context, here's a couple of snippits from our baseline
compiler source code:
protected final void emit_ldiv() {
// (1) zero check
asm.emitMOV_Reg_RegDisp(T0, SP, 0);
asm.emitOR_Reg_RegDisp(T0, SP, 4);
VM_ForwardReference fr1 = asm.forwardJcc(asm.NE);
asm.emitINT_Imm(VM_Runtime.TRAP_DIVIDE_BY_ZERO + RVM_TRAP_BASE); // trap
if divisor is 0
....
public final void emitINT_Imm (int v) {
if (VM.VerifyAssertions) VM._assert(v <= 0xFF);
int miStart = mi;
if (v == 3) { // special case interrupt
setMachineCodes(mi++, (byte) 0xCC);
} else {
setMachineCodes(mi++, (byte) 0xCD);
setMachineCodes(mi++, (byte) v);
}
if (lister != null) lister.I(miStart, "INT", v);
}
|