|
From: Christoph B. <bar...@or...> - 2006-09-11 08:25:31
|
Am Montag, 11. September 2006 00:41 schrieb Josef Weidendorfer:
> Hi Christoph,
>
> I just checked in a bug fix for this problem. Can you check if
> that fixes this issue for you?
>
> I did not look yet at the other bug (x86_64-specific?).
> I think the biggest problem is that toogling the instrumentation mode
> is not really fully tested.
>
> Josef
Hi,
the bug is still there. The current traceback is:
=3D=3D10690=3D=3D at 0x38014809: fprint_bbcc (global.h:691)
=3D=3D10690=3D=3D by 0x3801593D: print_bbccs_of_thread (dump.c:1550)
=3D=3D10690=3D=3D by 0x38015C3A: vgCallgrind_dump_profile (dump.c:1579)
=3D=3D10690=3D=3D by 0x38007651: vgCallgrind_check_command (command.c:45=
5)
=3D=3D10690=3D=3D by 0x38016CB2: vgCallgrind_run_thread (threads.c:191)
=3D=3D10690=3D=3D by 0x38035FFF: vgPlain_set_running (scheduler.c:218)
=3D=3D10690=3D=3D by 0x38048280: vgPlain_client_syscall (syswrap-main.c:=
812)
=3D=3D10690=3D=3D by 0x38036B7F: vgPlain_scheduler (scheduler.c:721)
=3D=3D10690=3D=3D by 0x38051339: run_a_thread_NORETURN (syswrap-linux.c:=
87)
I've attached a debugger and see the following values in line 691:
bb =3D 0x40210a748
*bb =3D {obj =3D 0x402100a70, offset =3D 591896, next =3D 0x0,=20
sect_kind =3D Vg_SectText, instr_count =3D 0, fn =3D 0x40210a678,=20
line =3D 0, is_entry =3D 0 '\0', bbcc_list =3D 0x40210a7d0,=20
last_bbcc =3D 0x40210a7d0, cjmp_count =3D 0, jmp =3D 0x40210a7a8,=20
jmpkind =3D 0, cjmp_inverted =3D 0 '\0', instr_len =3D 0,
cost_count =3D 0, instr =3D 0x40210a7a8}
b->instr[bb->instr_count-1] seems to be invalid because bb->instr_count is=
0=20
and bb->instr_count-1 is out of range.
Gru=DF
Christoph
|
|
From: Julian S. <js...@ac...> - 2006-09-11 09:58:18
|
> b->instr[bb->instr_count-1] seems to be invalid because bb->instr_count is > 0 and bb->instr_count-1 is out of range. That's interesting. I wonder if this happens when callgrind handles a block with zero instructions in, which can happen if the instruction decoder finds an unknown instruction. Christoph, does your program have anything like that (eg, it catches SIGILL and handles it, and/or you get messages about unknown instructions) ? J |
|
From: Christoph B. <bar...@or...> - 2006-09-11 10:09:47
|
Am Montag, 11. September 2006 11:58 schrieb Julian Seward:
> > b->instr[bb->instr_count-1] seems to be invalid because bb->instr_count
> > is 0 and bb->instr_count-1 is out of range.
>
> That's interesting. I wonder if this happens when callgrind handles a
> block with zero instructions in, which can happen if the instruction
> decoder finds an unknown instruction. Christoph, does your program
> have anything like that (eg, it catches SIGILL and handles it, and/or
> you get messages about unknown instructions) ?
>
Here is the whole programm:
extern "C" {
#include <unistd.h>
}
int main() {
while(true)
sleep(1);
}
Christoph
|
|
From: Julian S. <js...@ac...> - 2006-09-11 12:46:20
|
Josef
I could reproduce this on amd64 but not on x86. So I added the
following assertion (which seems like a good idea to add permanently)
Index: callgrind/global.h
===================================================================
--- callgrind/global.h (revision 6045)
+++ callgrind/global.h (working copy)
@@ -688,7 +688,8 @@
static __inline__ Addr bb_addr(BB* bb)
{ return bb->offset + bb->obj->offset; }
static __inline__ Addr bb_jmpaddr(BB* bb)
- { return bb->instr[bb->instr_count-1].instr_offset + bb->offset +
bb->obj->offset; }
+ { tl_assert(bb->instr_count > 0);
+ return bb->instr[bb->instr_count-1].instr_offset + bb->offset +
bb->obj->offset; }
/* from fn.c */
void CLG_(init_fn_array)(fn_array*);
and now I can reproduce it on x86 too. It's not amd64 specific,
maybe just bad luck that this example did not cause &bb->instr[0]
and &bb->instr[-1] to be in different pages on x86.
Anyway .. can you have a look at it?
Test program is:
#include <unistd.h>
int main() {
while(1)
sleep(1);
return 0;
}
This is on SuSE 10.0 (x86).
Run test program with callgrind, then in a new window do:
$prefix/bin/callgrind_control -i off
$prefix/bin/callgrind_control -i on
$prefix/bin/callgrind_control -d
and it crashes immediately.
J
On Monday 11 September 2006 11:09, Christoph Bartoschek wrote:
> Am Montag, 11. September 2006 11:58 schrieb Julian Seward:
> > > b->instr[bb->instr_count-1] seems to be invalid because
> > > bb->instr_count is 0 and bb->instr_count-1 is out of range.
> >
> > That's interesting. I wonder if this happens when callgrind handles a
> > block with zero instructions in, which can happen if the instruction
> > decoder finds an unknown instruction. Christoph, does your program
> > have anything like that (eg, it catches SIGILL and handles it, and/or
> > you get messages about unknown instructions) ?
>
> Here is the whole programm:
>
> extern "C" {
> #include <unistd.h>
> }
>
>
> int main() {
> while(true)
> sleep(1);
> }
>
> Christoph
>
> -------------------------------------------------------------------------
> Using Tomcat but need to do more? Need to support web services, security?
> Get stuff done quickly with pre-integrated technology to make your job
> easier Download IBM WebSphere Application Server v.1.0.1 based on Apache
> Geronimo
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
|
|
From: Josef W. <Jos...@gm...> - 2006-09-12 19:03:58
|
Hi Christoph, hi Julian,
I just got internet connection again...
Thanks for the detailed analysis.
The "BB with 0 instructions" is easy to explain, and the bug easy to
fix. It happens when you switch to full instrumentation (and callgrinds
call graph tracing) in the middle of a run: Whenever the shadow callstack
is empty, but callgrind sees a return instruction (ie. a shadow callstack
underrun), it creates an artifical BB which is faked to have called
the function we are returning from. This way, the call arc is noted and
will be in the profile data.
This bug seems to be in callgrind from the beginning, as old VGs more
or less also started in the middle of a run (when the VG shared lib
got control).
So
> + { tl_assert(bb->instr_count > 0);
is not correct.
Better do
======================================================================
--- global.h (Revision 6044)
+++ global.h (Arbeitskopie)
@@ -688,7 +688,8 @@
static __inline__ Addr bb_addr(BB* bb)
{ return bb->offset + bb->obj->offset; }
static __inline__ Addr bb_jmpaddr(BB* bb)
- { return bb->instr[bb->instr_count-1].instr_offset + bb->offset + bb->obj->offset; }
+ { UInt off = (bb->instr_count > 0) ? bb->instr[bb->instr_count-1].instr_offset : 0;
+ return off + bb->offset + bb->obj->offset; }
/* from fn.c */
void CLG_(init_fn_array)(fn_array*);
======================================================================
Josef
|
|
From: Julian S. <js...@ac...> - 2006-09-12 20:56:03
|
Hi Josef,
That's great - it does seem to fix it, at least on amd64. Did not
test on x86. I'll push it into 3.2.1.
J
On Tuesday 12 September 2006 20:03, Josef Weidendorfer wrote:
> Hi Christoph, hi Julian,
>
> I just got internet connection again...
> Thanks for the detailed analysis.
>
> The "BB with 0 instructions" is easy to explain, and the bug easy to
> fix. It happens when you switch to full instrumentation (and callgrinds
> call graph tracing) in the middle of a run: Whenever the shadow callstack
> is empty, but callgrind sees a return instruction (ie. a shadow callstack
> underrun), it creates an artifical BB which is faked to have called
> the function we are returning from. This way, the call arc is noted and
> will be in the profile data.
>
> This bug seems to be in callgrind from the beginning, as old VGs more
> or less also started in the middle of a run (when the VG shared lib
> got control).
>
> So
>
> > + { tl_assert(bb->instr_count > 0);
>
> is not correct.
> Better do
>
> ======================================================================
> --- global.h (Revision 6044)
> +++ global.h (Arbeitskopie)
> @@ -688,7 +688,8 @@
> static __inline__ Addr bb_addr(BB* bb)
> { return bb->offset + bb->obj->offset; }
> static __inline__ Addr bb_jmpaddr(BB* bb)
> - { return bb->instr[bb->instr_count-1].instr_offset + bb->offset +
> bb->obj->offset; } + { UInt off = (bb->instr_count > 0) ?
> bb->instr[bb->instr_count-1].instr_offset : 0; + return off + bb->offset
> + bb->obj->offset; }
>
> /* from fn.c */
> void CLG_(init_fn_array)(fn_array*);
> ======================================================================
>
>
> Josef
>
> -------------------------------------------------------------------------
> Using Tomcat but need to do more? Need to support web services, security?
> Get stuff done quickly with pre-integrated technology to make your job
> easier Download IBM WebSphere Application Server v.1.0.1 based on Apache
> Geronimo
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
|