This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
bytecode question
- From: Nicholas Mc Guire <mcguire at lzu dot edu dot cn>
- To: gdb at sources dot redhat dot com
- Date: Sun, 16 Apr 2006 22:57:35 +0800
- Subject: bytecode question
HI !
I'm still fighting with bytecode in gdb tracepoints - wrote up a brute
froce interpreter for the bytecode and it seems to be doing something
resonable - just the values finaly collected are plain wrong :)
collecting memory and registers is working ok (and delivering the right
values).
Host side:
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x400007b0 in ?? ()
(gdb) symbol-file gdbserver/hello
Reading symbols from /root/tracepoints/gdb-6.3-tp2/gdb/gdbserver/hello...done.
(gdb) trace 28
Tracepoint 1 at 0x80483f2: file hello.c, line 28.
(gdb) act
Enter actions for tracepoint 1, one per line.
End with a line saying just "end".
> col junk
> end
(gdb) tstart
(gdb) c
Continuing.
Program exited normally.
Junk is statically initialized to 40 at line 27 in the test
case code - but this (and in fact all other variables checked)
are finaly collected with a value of 00000000.
Target response:
<snip>
tracepoint 1 triggert at 80483f2
found 1 actions for this tp
action length 13, code 26000422000222040322040c27
collecting reg 4 = befef5e4
Trace at befef5e0 (size 4)
dump size 4, data 00000000
bc done
Child exited with retcode = 0
The interpreter loop:
removed all the cases not needed here - the post is overly long allreadyi
sorry for that.
My suspicion is that the way I'm collecting the registers in case 0x26
(bytecode register) is collecting the wrong register content in this case
(value 0x4 is sp on x86) - any idea what could be wrong here ?
I called set_desired_inferior in the entry function (the tracepoint handler)
that then called dump_bytecode - must one do anything more to get hold of
the registers of the application being traced ?
int
dump_bytecode(struct tp_bytecode *bytecode)
{
int i=0;
char *bc;
printf("action length %d, code %s\n",
bytecode->len,
bytecode->agent_expression);
bc=malloc(bytecode->len);
memset(bc,0,bytecode->len);
unhexify(bc,bytecode->agent_expression,bytecode->len);
/* brute force interpreter */
for(i=0;i<bytecode->len;){
switch(bc[i++]){
case 0x02:
push(pop() + pop());
break;
case 0x03:
{
unsigned int tmp = pop();
push(pop() - tmp);
}
break;
case 0x04:
push(pop() * pop());
break;
case 0x0c:
{
char dump[256];
char *buf;
unsigned int size = pop();
unsigned int addr = pop();
buf = malloc(size);
printf("Trace at %x (size %d)\n",
addr,size);
read_inferior_memory(addr,buf,size);
hexify (dump, buf, sizeof(buf));
printf("dump size %d, data %s\n",
size,
dump);
}
break;
case 0x19:
{
unsigned int addr=0;
unsigned char data[4];
unsigned int val=0;
addr=pop();
read_inferior_memory (addr, data, 4);
val = (data [3] << 24);
val += (data [2] << 16);
val += (data [1] << 8 );
val += (data [0] << 0 );
push(val);
}
break;
case 0x22:
push(bc[i++]);
break;
case 0x23:
{
unsigned int tmp = 0;
tmp = (bc[i++] << 8);
tmp += (bc[i++] << 0);
push(tmp);
}
break;
case 0x24:
{
unsigned int tmp = 0;
tmp = (bc[i++] << 24);
tmp += (bc[i++] << 16);
tmp += (bc[i++] << 8 );
tmp += (bc[i++] << 0 );
push(tmp);
}
break;
case 0x26:
{
char buf[4];
unsigned int val = 0;
unsigned int regno = 0;
regno = (bc[i++] << 8);
regno += (bc[i++] << 0);
//set_desired_inferior (0);
collect_register(regno, buf);
val = (buf[3] << 24);
val += (buf[2] << 16);
val += (buf[1] << 8 );
val += (buf[0] << 0 );
printf("collecting reg %x = %x\n",
regno,val);
push(val);
}
break;
case 0x27:
printf("bc done\n");
break;
default:
printf("invalide opcode %x\n",(unsigned)bc[i-1]);
break;
}
}