This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

libstdc++-v3 testsuite bug -- uninitialized variable



I was tracking down a "regression" which showed up after some changes
on the tree-ssa branch.  The fun part was that the test would sometimes
pass and sometimes fail (using the exact same test binary).  Classic
symptoms of an uninitialized variable.

If we look at:

  testsuite/22_locale/ctype/is/wchar_t/1.cc

We have the following assignments/references to m02:


  std::ctype_base::mask m02[13];
[ ... ]
  cc1 = gctype.is(cc0, cc0 + 13, m02);
  VERIFY( cc1 == strlit01 + 13);


There are no other references or assignments to m02.


So, at least to a C hacker it appears that m02 is uninitialized.  This
theory is further supported by a little debugging...

If I stop on the cc1 = gctype.is statement and print the contents of
m02, I get random junk which varies from one run to the next.  Depending
on the precise junk in m02 the VERIFY statement may pass or fail.

Unfortunately, C++ as a language makes it bloody impossible AFAICT to
look at a variable declaration like the one shown above and know if
it's initialized or not (after all, the type could have a constructor
which would initialize the variable).

Rather than try to work backwards through the C++ code to determine if
the type has a constructor, I set up the debugger to tell me about any
accesses to the memory location for m02[0].  ie, I will get notified of
either reads or writes.  The only difficulty here is that newer kernels
give you a different starting stack address (it may be part of the exec-shield
feature).  Luckily the offset between the stack pointer in main and the m02
variable in test01 does not vary.

Anyway, I put a breakpoint in main to get control of the test, then place
an "awatch" on the appropriate location for 'm02[0]' -- note this is done
before test01 is invoked by knowing that 'm02[0]' will be at a known offset
from main's stack pointer. 

I let the program continue and the first hit I get on my watchpoint is in:

0x400a574b in std::ctype<wchar_t>::do_is(wchar_t const*, wchar_t const*, unsigned short*) const (this=0xbff96930, __lo=0xbff96940, __hi=0xbff96974, 
    __m=0xbff96900) at ctype_members.cc:142
142         while (__lo < __hi && !this->do_is(*__m, *__lo))


Which is read, not a write.  ie, we just read from m, but m was never
initialized.


Anyway, I'm not sure how you expected/wanted m02 to be initialized
in that test, so I'm not going to try and fix it -- I'll leave the
fixing to you.  I'll note that similar code appears in the "char"
version of the same test, so you might want to fix it at the same
time.

Cheers,

Jeff


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]