stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Travis Vitek" <tvi...@quovadx.com>
Subject RE: Purify run results
Date Fri, 05 Oct 2007 18:38:37 GMT
 

>From: Martin Sebor [mailto:msebor@gmail.com] On Behalf Of Martin Sebor
>
>Travis Vitek wrote:
>
>> I spent some time looking through these results and it looks 
>> like the HP compiler is generating code that results in many
>> unexpected UMR [Uninitialized Memory Read] errors.
>
>The UMR is real, isn't it? I.e., __tag is not initialized but
>it's being copied to the function argument.

Yes, I agree that it is real. The empty object is allocated on the
stack, but that stack space is not initialized with anything. i.e. The
compiler generates code that results in a UMR reported by Purify. Got
any bright ideas on how to fix it from C++ without adding a data member
to the empty object?

I can easily ignore the hundreds of UMR warnings that are caused by the
problem, but others looking at the purify results should be made aware
that there doesn't really appear to be anything _reasonable_ that we can
do about it.

Interestingly enough, Purify on HP does _not_ report a UMR if I just
copy the tag object that is not uninitialized...

;;; File: t.cpp
;;;  15 {
0x2cec <main>:  nop
0x2cf0 <main+0x4>:      stw %rp,-0x14(%sp)
0x2cf4 <main+0x8>:      ldo 0x40(%sp),%sp
0x2cf8 <main+0xc>:      call 0x2cdc <_main>
0x2cfc <main+0x10>:     nop
;;;  18     random_access_iterator_tag __tag2(__tag);
0x2d00 <main+0x14>:     ldb -0x38(%sp),%r1 ; <- load __tag into r1
0x2d04 <main+0x18>:     stb %r1,-0x37(%sp) ; <- store r1 into __tag2
;;;  19     random_access_iterator_tag __tag3(__tag2);
0x2d08 <main+0x1c>:     ldb -0x37(%sp),%r31 ; <- load __tag2 into r31
0x2d0c <main+0x20>:     stb %r31,-0x36(%sp) ; <- store r31 into __tag3
;;;  21     return 0;
0x2d10 <main+0x24>:     ldi 0,%ret0
;;;  22 }
0x2d14 <main+0x28>:     copy %ret0,%ret0
0x2d18 <main+0x2c>:     ldw -0x54(%sp),%rp
0x2d1c <main+0x30>:     ret 
End of assembler dump.


>
>Do other compilers eliminate the copy?
>

No.

Purify for Windows does not report a UMR on the same code, but I don't
see anything in the assembly that initializes the empty object there
either.

int main()
{
00411920  push        ebp  
00411921  mov         ebp,esp 
00411923  push        ecx  
    random_access_iterator_tag __tag;
    distance (__tag); // <-- umr here
00411924  mov         al,byte ptr [__tag] 
00411927  push        eax  
00411928  call        distance (40101Eh) 
0041192D  add         esp,4 

    return 0;
00411930  xor         eax,eax 
}
00411932  mov         esp,ebp 
00411934  pop         ebp  
00411935  ret

Purify on linux/gcc reports no UMR warnings with my testcase either. I
tried to parse through the assembly generated by gcc, but it was insane.
It turned that simple main into 185 instructions. MSVC boils it down to
the 11 instructions above.

I did find that I got very similar UMR errors with std::bind1st/bind2nd
on linux/gcc. The first parameter passed to these functions is usually
an empty function object, and the UMR is reported when copying that. So
it is essentially the same problem, just a different context.

It looks like Purify is trying to detect and ignore the issue of the
uninitialized empty object [that must be at least 1 byte in size], but
it doesn't always do so.

Travis




Mime
View raw message