|
From: João M. S. S. <joa...@gm...> - 2015-04-07 16:22:21
|
Hi,
I'm trying to debug a program with memcheck. There is an error:
--19524-- memcheck GC: 1000 nodes, 419 survivors (41.9%)
--19524-- memcheck GC: 1014 new table size (driftup)
--19524-- REDIR: 0x72c60c0 (libc.so.6:__strspn_sse42) redirected to
0x4c32010 (strspn)
==19524== Conditional jump or move depends on uninitialised value(s)
==19524== at 0x5A1E317:
tesseract::Tesseract::quality_based_rejection(PAGE_RES_IT&, unsigned
char) (docqual.cpp:145)
==19524== by 0x5A11871:
tesseract::Tesseract::rejection_passes(PAGE_RES*, ETEXT_DESC*, TBOX
const*, char const*) (control.cpp:680)
==19524== by 0x5A1551E:
tesseract::Tesseract::recog_all_words(PAGE_RES*, ETEXT_DESC*, TBOX
const*, char const*, int) (control.cpp:371)
==19524== by 0x5A05D93:
tesseract::TessBaseAPI::Recognize(ETEXT_DESC*) (baseapi.cpp:747)
==19524== by 0x5A05F7C: tesseract::TessBaseAPI::GetUTF8Text()
(baseapi.cpp:1019)
==19524== by 0x41D2D1: Tesseract::ocr(cv::Mat) (Tesseract.cpp:26)
==19524== by 0x4066F8: main (test.cpp:206)
==19524==
==19524==
==19524== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- y
and then I attach to gdb but get:
Failed to read a valid object file image from memory.
0x0000000005a1e317 in tesseract::Tesseract::quality_based_rejection
(this=this@entry=0x1a47b780, page_res_it=...,
good_quality_doc=good_quality_doc@entry=1 '\001') at docqual.cpp:145
145 if ((tessedit_good_quality_unrej && good_quality_doc))
(gdb) p tessedit_good_quality_unrej
$1 = {<tesseract::Param> = {name_ = 0x5bdf54f
"tessedit_good_quality_unrej", info_ = 0x5bdf56b "Reduce rejection on
good docs", init_ = false,
debug_ = false}, value_ = 1 '\001', params_vec_ = 0x1a47b9a0}
(gdb) p good_quality_doc
$2 = 1 '\001'
What does "Failed to read a valid object file image from memory" mean?
Does it come from gdb or may be caused upstream by valgrind?
This is a "Conditional jump or move" error but the variables, as printed
above in gdb, seem initialized? So it this a false positive?
Any help?
Thanks.
--
João M. S. Silva
|
|
From: Philippe W. <phi...@sk...> - 2015-04-07 19:59:01
|
On Tue, 2015-04-07 at 17:22 +0100, "João M. S. Silva" wrote: > Hi, > > I'm trying to debug a program with memcheck. There is an error: > > --19524-- memcheck GC: 1000 nodes, 419 survivors (41.9%) > --19524-- memcheck GC: 1014 new table size (driftup) > --19524-- REDIR: 0x72c60c0 (libc.so.6:__strspn_sse42) redirected to > 0x4c32010 (strspn) > ==19524== Conditional jump or move depends on uninitialised value(s) > ==19524== at 0x5A1E317: > tesseract::Tesseract::quality_based_rejection(PAGE_RES_IT&, unsigned > char) (docqual.cpp:145) > ==19524== by 0x5A11871: > tesseract::Tesseract::rejection_passes(PAGE_RES*, ETEXT_DESC*, TBOX > const*, char const*) (control.cpp:680) > ==19524== by 0x5A1551E: > tesseract::Tesseract::recog_all_words(PAGE_RES*, ETEXT_DESC*, TBOX > const*, char const*, int) (control.cpp:371) > ==19524== by 0x5A05D93: > tesseract::TessBaseAPI::Recognize(ETEXT_DESC*) (baseapi.cpp:747) > ==19524== by 0x5A05F7C: tesseract::TessBaseAPI::GetUTF8Text() > (baseapi.cpp:1019) > ==19524== by 0x41D2D1: Tesseract::ocr(cv::Mat) (Tesseract.cpp:26) > ==19524== by 0x4066F8: main (test.cpp:206) > ==19524== > ==19524== > ==19524== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- y --db-attach=yes is deprecated in 3.10 and will be removed (sooner or later). Better use the Valgrind gdbserver. See http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver for more information. Philippe |
|
From: João M. S. S. <joa...@gm...> - 2015-04-07 22:10:21
|
> --db-attach=yes is deprecated in 3.10 > and will be removed (sooner or later). > > Better use the Valgrind gdbserver. > > See > http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver > for more information. Thanks for the vgdb suggestion. I've tried it before but with --vgdb-error=1. With --vgdb-error=0 like suggested in the manual you indicate, and running gdb in another shell, I was able to eliminate the "Failed to read a valid object file image from memory" error. However, the possibly uninitialized variables seem initialized as before. With --track-origins=yes, I see: ==3541== Uninitialised value was created by a stack allocation ==3541== at 0x5A11639: tesseract::Tesseract::rejection_passes(PAGE_RES*, ETEXT_DESC*, TBOX const*, char const*) (control.cpp:591) I'm not familiar with Tesseract's code, but it seems to indicate that in the call in line 591 of control.cpp: quality_based_rejection(page_res_it, good_quality_doc); One of the arguments is uninitialized when passed through the stack. And if, inside the function, the error is in line 145 of docqual.cpp: if ((tessedit_good_quality_unrej && good_quality_doc)) then "good_quality_doc" should be the culprit (not "page_res_it"). But this is a boolean correctly initialized: (gdb) p good_quality_doc $1 = 1 '\001' Any further hints? -- João M. S. Silva |
|
From: Philippe W. <phi...@sk...> - 2015-04-09 18:11:55
|
On Tue, 2015-04-07 at 23:10 +0100, "João M. S. Silva" wrote: > > --db-attach=yes is deprecated in 3.10 > > and will be removed (sooner or later). > > > > Better use the Valgrind gdbserver. > > > > See > > http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver > > for more information. > > Thanks for the vgdb suggestion. > > I've tried it before but with --vgdb-error=1. > > With --vgdb-error=0 like suggested in the manual you indicate, and > running gdb in another shell, I was able to eliminate the "Failed to > read a valid object file image from memory" error. > > However, the possibly uninitialized variables seem initialized as before. > > With --track-origins=yes, I see: > > ==3541== Uninitialised value was created by a stack allocation > ==3541== at 0x5A11639: > tesseract::Tesseract::rejection_passes(PAGE_RES*, ETEXT_DESC*, TBOX > const*, char const*) (control.cpp:591) > > I'm not familiar with Tesseract's code, but it seems to indicate that in > the call in line 591 of control.cpp: > > quality_based_rejection(page_res_it, good_quality_doc); > > One of the arguments is uninitialized when passed through the stack. > > And if, inside the function, the error is in line 145 of docqual.cpp: > > if ((tessedit_good_quality_unrej && good_quality_doc)) > > then "good_quality_doc" should be the culprit (not "page_res_it"). But > this is a boolean correctly initialized: > > (gdb) p good_quality_doc > $1 = 1 '\001' > > Any further hints? > The origin (i.e. the stack allocation) is one of the local variables in the function which is at line 591. Valgrind cannot give a more precise indication of which variable. Why the created by a stack allocation points somewhere inside a function rather than at the beginning of the function I do not know. Might depend on the way the compiler has optimised. What you can further do is to use the memcheck monitor commands to examine the definedness of the variables used on the line where the error is detected. See manual for more info http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.monitor-commands Philippe |
|
From: João M. S. S. <joa...@gm...> - 2015-04-14 18:26:52
|
> What you can further do is to use the memcheck monitor commands to > examine the definedness of the variables used on the line where the > error is detected. > > See manual for more info > http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.monitor-commands Thanks, I didn't know about the "monitor get_vbits" command. However, it seems I'm not able to catch any uninitialized variable. I also get this kind of error in another library: ==17108== Use of uninitialised value of size 8 ==17108== at 0x60BDB6D: decode_rs_char (decode_rs.h:118) ==17108== by 0x41D9B5: Code::decode(unsigned char*, int*, unsigned int, bool) (Code.cpp:114) ==17108== by 0x41E6D8: Code::extract(char*, char*, std::string&, unsigned int) (Code.cpp:326) ==17108== by 0x4060E4: main (test.cpp:178) ==17108== Uninitialised value was created by a stack allocation ==17108== at 0x60BD480: decode_rs_char (decode_rs_char.c:15) And with vgdb I get this in gdb: Program received signal SIGTRAP, Trace/breakpoint trap. 0x00000000060bdb6d in decode_rs_char (p=0x201aac50, data=0xffefff500 "", eras_pos=0xffefff480, no_eras=22) at decode_rs.h:118 118 tmp = INDEX_OF[lambda[j - 1]]; I tried the get_vbits command in variables p, data, eras_pos and no_eras. I had to manually find out the size of the corresponding variables, since some of them are pointers or structs with pointer fields. I seem to have computed the corresponding sizes correctly since if I use a size 1 byte larger in the vget_bits command I get an "unaddressable" warning (also represented by the underscore). When you say "local variables" you mean the variables the function received as argument or all variables defined inside the function? I think I know the answer, since I remember having discussed this in the mailing list: all variables inside the function are local, thus allocated in the stack, so valgrind is not yet able to detect errors in them? Can you confirm this? I have to try using exp-sgcheck, right? Thanks. -- João M. S. Silva |
|
From: João M. S. S. <joa...@gm...> - 2015-04-14 21:03:19
|
> I do not understand. The below error is an uninitialised value error. > Why do you say you cannot catch the errors ? Valgrind points to them, but I don't seem to confirm the uninitialization. > You just have to use monitor get_vbits at the time of the error > to investigate more in depth where the error comes from, > and if needed, relaunch the execution after having added some > breakpoints earlier in the program flow, and again use get_vbits > to try to understand where the uninit error comes from. Easier said than done :) I've tried but there are a lot of local variables: int retval; struct rs *rs = (struct rs *)p; int deg_lambda, el, deg_omega; int i, j, r,k; data_t u,q,tmp,num1,num2,den,discr_r; data_t lambda[NROOTS+1], s[NROOTS]; /* Err+Eras Locator poly * and syndrome poly */ data_t b[NROOTS+1], t[NROOTS+1], omega[NROOTS+1]; data_t root[NROOTS], reg[NROOTS+1], loc[NROOTS]; int syn_error, count; and lines where they can be used before initialization: ~ 300. > Yes, the monitor get_vbits only knows about address+length. > So, you need to do something like > (gdb) p &myvar > (gdb) p sizeof(myvar) > and then use > (gdb) monitor get_vbits <address> <size> > to get the vbits. Yes, but in some cases the sizeof indicates the size of the pointer (not the size of the allocated memory). So I had to browse the code to get the size of the allocations/structs involved. > When valgrind reports that the origin of an uninit var is in a function, > then it means it is one of the local variables of the function. > Not the arguments of this function. OK, that's why it is difficult to find this. Specially because it is a 3rd party library. Since the line valgrind pinpoints is not accurate/relevant, we are in doubt about where the error comes from. (I'm not saying its valgrind's fault, of course, it already is an extremely useful tool, as is). > If you want to detect buffer over or under run in stack and global > variables, then yes, the experimental exp-sgcheck tool is your friend. OK, so it is not applicable to this case of uninitialized stack variables. What is strange is that I never faced such a shortcoming in my own code. In my code valgrind always points to the location of the error exactly. Does this happen because this is a library that I link with? Or because of the nature of the error? Thanks. -- João M. S. Silva |
|
From: Philippe W. <phi...@sk...> - 2015-04-14 21:34:25
|
On Tue, 2015-04-14 at 22:03 +0100, "João M. S. Silva" wrote: > > Yes, but in some cases the sizeof indicates the size of the pointer (not > the size of the allocated memory). So I had to browse the code to get > the size of the allocations/structs involved. or use (gdb) monitor v.info location <addr> You might also better start your valgrind with --read-var-info=yes That might give some more information in some cases (valgrind will be slower to startup). > OK, so it is not applicable to this case of uninitialized stack variables. sg-check will not help for such an uninit. > > What is strange is that I never faced such a shortcoming in my own code. > In my code valgrind always points to the location of the error exactly. > Does this happen because this is a library that I link with? Or because > of the nature of the error? Depends on what errors you had in your code. Uninit errors can be more difficult to track than leaks or dangling pointers, in particular because the origin of uninit data is not precisely maintained. Philippe |
|
From: Philippe W. <phi...@sk...> - 2015-04-14 21:28:47
|
On Tue, 2015-04-14 at 19:26 +0100, "João M. S. Silva" wrote: > Program received signal SIGTRAP, Trace/breakpoint trap. > 0x00000000060bdb6d in decode_rs_char (p=0x201aac50, data=0xffefff500 "", > eras_pos=0xffefff480, no_eras=22) at decode_rs.h:118 > 118 tmp = INDEX_OF[lambda[j - 1]]; > > I tried the get_vbits command in variables p, data, eras_pos and > no_eras. I had to manually find out the size of the corresponding > variables, since some of them are pointers or structs with pointer fields. But the most probably culprits are either j or lambda[j-1] or whatever the INDEX_OF macro(is it a macro?) is doing behind what is visible. There is no (direct) use of the function args on line 118. Of course, it might be that e.g. an uninitialised arg (e.g. no_eras might be unitialised and get a random value 22) might result later in j or whatever being initialised. Philippe |
|
From: João M. S. S. <joa...@gm...> - 2015-04-15 00:06:12
|
> But the most probably culprits are either j or lambda[j-1] > or whatever the INDEX_OF macro(is it a macro?) is doing behind > what is visible. > There is no (direct) use of the function args on line 118. > Of course, it might be that e.g. an uninitialised arg (e.g. no_eras > might be unitialised and get a random value 22) might result later in j > or whatever being initialised. I already tried get_vbits on j (size 4), lambda (size 21) and INDEX_OF = rs->index_of (size 32) and all of them seem initialized (represented with 0 by get_vbits). I also tried --read-var-info=yes but as far as I can see there is no difference in the output. -- João M. S. Silva |
|
From: João M. S. S. <joa...@gm...> - 2015-04-15 00:59:05
|
> There is no (direct) use of the function args on line 118.
> Of course, it might be that e.g. an uninitialised arg (e.g. no_eras
> might be unitialised and get a random value 22) might result later in j
> or whatever being initialised.
You're right, I think I found it. In:
tmp = INDEX_OF[lambda[j - 1]];
j gets = 22 but lambda is size 21.
This happens because no_eras = 22:
for (i = 1; i < no_eras; i++) {
u = MODNN(PRIM*(NN-1-eras_pos[i]));
for (j = i+1; j > 0; j--) {
tmp = INDEX_OF[lambda[j - 1]];
if(tmp != A0)
lambda[j] ^= ALPHA_TO[MODNN(u + tmp)];
}
}
I missed it before.
Thanks.
--
João M. S. Silva
|
|
From: João M. S. S. <joa...@gm...> - 2015-04-16 12:24:13
|
> I defined a gdb-macro for this: > > define get_vbits > printf "# mon get_vbits 0x%lx 0x%lx\n" , &$arg0 , sizeof($arg0) > eval "mon get_vbits 0x%lx 0x%lx" , &$arg0 , sizeof($arg0) > end > > Then I can run: > (gdb) get_vbits i_Cond > # mon get_vbits 0xffefff8bf 0x1 > 00 > (gdb) Thanks for the hints. The sizeof() only works for variables, not pointers, right? gdb should not know about the size of the allocated memory, but valgrind should know that, since it checks for out-of-bounds access. Is this correct? > For the case above, you should check the instruction triggering the error. > (gdb) x/i $rip > > Then you know in what register to look for. with the complete > disassembly you might be able to track down what it exactly was. > Then look near the problematic instruction. > (gdb) disassemble /m > > I think there was also some option to switch valgrind so that the > definedness of registers can be checked: --vgdb-shadow-registers=yes -- João M. S. Silva |
|
From: Philippe W. <phi...@sk...> - 2015-04-16 17:19:15
|
On Thu, 2015-04-16 at 13:24 +0100, "João M. S. Silva" wrote:
> > I defined a gdb-macro for this:
> >
> > define get_vbits
> > printf "# mon get_vbits 0x%lx 0x%lx\n" , &$arg0 , sizeof($arg0)
> > eval "mon get_vbits 0x%lx 0x%lx" , &$arg0 , sizeof($arg0)
> > end
> >
> > Then I can run:
> > (gdb) get_vbits i_Cond
> > # mon get_vbits 0xffefff8bf 0x1
> > 00
> > (gdb)
>
> Thanks for the hints. The sizeof() only works for variables, not
> pointers, right?
Yes, it works for pointer. sizeof of a pointer returns the size of
the pointer :). So, 4 or 8 bytes, depending on the arch.
If the pointer is to a fixed size known struct, then you should
be able to use (I did not try).
get_vbits *pointer
Finally, effectively, memcheck knows where a ptr points
(if the ptr is valid).
So, it should be possible to write a gdb command (probably difficult to
do, the gdb macro language is not very powerful) or a python extension
to do a more intelligent get_vbits which would use
the type info known by gdb
and/or
monitor v.info location <address>
to have an idea about the size of the block.
and then do the correct monitor get_vbits command.
Anybody volunteering ?
We could add a file with 'various valgrind related gdb python extension'
as part of the Valgrind distribution.
> > I think there was also some option to switch valgrind so that the
> > definedness of registers can be checked: --vgdb-shadow-registers=yes
Yes, when giving this option, you can examine the definedness of a
register by printing its shadow 1 register.
For example,
p $eaxs1
shows the definedness of the eax register.
See
http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver-shadowregisters
and
http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.monitor-commands
Philippe
|
|
From: João M. S. S. <joa...@gm...> - 2015-04-16 17:39:25
|
> Finally, effectively, memcheck knows where a ptr points > (if the ptr is valid). > So, it should be possible to write a gdb command (probably difficult to > do, the gdb macro language is not very powerful) or a python extension > to do a more intelligent get_vbits which would use > the type info known by gdb > and/or > monitor v.info location <address> > to have an idea about the size of the block. > and then do the correct monitor get_vbits command. > Anybody volunteering ? > We could add a file with 'various valgrind related gdb python extension' > as part of the Valgrind distribution. I'm of course ignorant about how memcheck works, but if it checks for out-of-bounds accesses, by knowing the size of each allocation (by wrapping malloc or so), wouldn't it be possible for valgrind to pinpoint the error directly, instead of having to recur to gdb? I mean, if valgrind is able to signal with 0 or 1 if a byte was initialized (monitor get_vbits) then it should be able to tell the user which variable was not initialized? Unless it works on the memory space level, not on the variable level... OK. -- João M. S. Silva |
|
From: Philippe W. <phi...@sk...> - 2015-04-14 19:24:05
|
On Tue, 2015-04-14 at 19:26 +0100, "João M. S. Silva" wrote: > > What you can further do is to use the memcheck monitor commands to > > examine the definedness of the variables used on the line where the > > error is detected. > > > > See manual for more info > > http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.monitor-commands > > Thanks, I didn't know about the "monitor get_vbits" command. > > However, it seems I'm not able to catch any uninitialized variable. I do not understand. The below error is an uninitialised value error. Why do you say you cannot catch the errors ? You just have to use monitor get_vbits at the time of the error to investigate more in depth where the error comes from, and if needed, relaunch the execution after having added some breakpoints earlier in the program flow, and again use get_vbits to try to understand where the uninit error comes from. > I > also get this kind of error in another library: > > ==17108== Use of uninitialised value of size 8 > ==17108== at 0x60BDB6D: decode_rs_char (decode_rs.h:118) > ==17108== by 0x41D9B5: Code::decode(unsigned char*, int*, unsigned > int, bool) (Code.cpp:114) > ==17108== by 0x41E6D8: Code::extract(char*, char*, std::string&, > unsigned int) (Code.cpp:326) > ==17108== by 0x4060E4: main (test.cpp:178) > ==17108== Uninitialised value was created by a stack allocation > ==17108== at 0x60BD480: decode_rs_char (decode_rs_char.c:15) > > And with vgdb I get this in gdb: > > Program received signal SIGTRAP, Trace/breakpoint trap. > 0x00000000060bdb6d in decode_rs_char (p=0x201aac50, data=0xffefff500 "", > eras_pos=0xffefff480, no_eras=22) at decode_rs.h:118 > 118 tmp = INDEX_OF[lambda[j - 1]]; Yes that is the way the valgrind gdbserver reports to gdb that there is an error that the user can look at. > > I tried the get_vbits command in variables p, data, eras_pos and > no_eras. I had to manually find out the size of the corresponding > variables, since some of them are pointers or structs with pointer fields. Yes, the monitor get_vbits only knows about address+length. So, you need to do something like (gdb) p &myvar (gdb) p sizeof(myvar) and then use (gdb) monitor get_vbits <address> <size> to get the vbits. > > I seem to have computed the corresponding sizes correctly since if I use > a size 1 byte larger in the vget_bits command I get an "unaddressable" > warning (also represented by the underscore). > > When you say "local variables" you mean the variables the function > received as argument or all variables defined inside the function? When valgrind reports that the origin of an uninit var is in a function, then it means it is one of the local variables of the function. Not the arguments of this function. > > I think I know the answer, since I remember having discussed this in the > mailing list: all variables inside the function are local, thus > allocated in the stack, so valgrind is not yet able to detect errors in > them? Can you confirm this? Valgrind memcheck is able to report some errors originating from local vars, namely the uninit errors. > > I have to try using exp-sgcheck, right? If you want to detect buffer over or under run in stack and global variables, then yes, the experimental exp-sgcheck tool is your friend. Philippe |
|
From: Matthias S. <zz...@ge...> - 2015-04-15 18:50:55
|
On 14.04.2015 21:24, Philippe Waroquiers wrote: > On Tue, 2015-04-14 at 19:26 +0100, "João M. S. Silva" wrote: >>> What you can further do is to use the memcheck monitor commands to >>> examine the definedness of the variables used on the line where the >>> error is detected. >>> >>> See manual for more info >>> http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.monitor-commands >> >> Thanks, I didn't know about the "monitor get_vbits" command. >> >> However, it seems I'm not able to catch any uninitialized variable. > I do not understand. The below error is an uninitialised value error. > Why do you say you cannot catch the errors ? > You just have to use monitor get_vbits at the time of the error > to investigate more in depth where the error comes from, > and if needed, relaunch the execution after having added some > breakpoints earlier in the program flow, and again use get_vbits > to try to understand where the uninit error comes from. > >> I >> also get this kind of error in another library: >> >> ==17108== Use of uninitialised value of size 8 >> ==17108== at 0x60BDB6D: decode_rs_char (decode_rs.h:118) >> ==17108== by 0x41D9B5: Code::decode(unsigned char*, int*, unsigned >> int, bool) (Code.cpp:114) >> ==17108== by 0x41E6D8: Code::extract(char*, char*, std::string&, >> unsigned int) (Code.cpp:326) >> ==17108== by 0x4060E4: main (test.cpp:178) >> ==17108== Uninitialised value was created by a stack allocation >> ==17108== at 0x60BD480: decode_rs_char (decode_rs_char.c:15) >> >> And with vgdb I get this in gdb: >> >> Program received signal SIGTRAP, Trace/breakpoint trap. >> 0x00000000060bdb6d in decode_rs_char (p=0x201aac50, data=0xffefff500 "", >> eras_pos=0xffefff480, no_eras=22) at decode_rs.h:118 >> 118 tmp = INDEX_OF[lambda[j - 1]]; > Yes that is the way the valgrind gdbserver reports to gdb that there is > an error that the user can look at. > >> >> I tried the get_vbits command in variables p, data, eras_pos and >> no_eras. I had to manually find out the size of the corresponding >> variables, since some of them are pointers or structs with pointer fields. > Yes, the monitor get_vbits only knows about address+length. > So, you need to do something like > (gdb) p &myvar > (gdb) p sizeof(myvar) > and then use > (gdb) monitor get_vbits <address> <size> > to get the vbits. > I defined a gdb-macro for this: define get_vbits printf "# mon get_vbits 0x%lx 0x%lx\n" , &$arg0 , sizeof($arg0) eval "mon get_vbits 0x%lx 0x%lx" , &$arg0 , sizeof($arg0) end Then I can run: (gdb) get_vbits i_Cond # mon get_vbits 0xffefff8bf 0x1 00 (gdb) For the case above, you should check the instruction triggering the error. (gdb) x/i $rip Then you know in what register to look for. with the complete disassembly you might be able to track down what it exactly was. Then look near the problematic instruction. (gdb) disassemble /m I think there was also some option to switch valgrind so that the definedness of registers can be checked: --vgdb-shadow-registers=yes Regards Matthias |