Updates:
        Status: Assigned
        Owner: erik...@chromium.org

Comment #5 on issue 5309 by ero...@chromium.org: uninitialized memory read  
in LayoutTests\svg\W3C-SVG-1.1\text-intro-05-t.svg
http://code.google.com/p/chromium/issues/detail?id=5309

It looks like Purify is getting confused when zero-extending a 'word ptr'  
(stack) to a DWORD register.

   movzx   edx,word ptr [ecx+eax*2]

versus

   mov     dx,word ptr [ecx+eax*2]

Purify reports the UMR as a 1 byte access from the stack, and at an  
incorrect instruction offset (but near a movzx).
This is odd since the blamed line does not in fact do any BYTE ptr  
accesses, but only WORD ptr.

By doing a trivial code transformation (that doesn't change the meaning of  
the code, but does change the generated assembly), I can get the problem to  
go away.

==============================================
Original code
==============================================
static bool ContainsMissingGlyphs(WORD *glyphs,
                                   int length,
                                   SCRIPT_FONTPROPERTIES* properties)
{
     for (int i = 0; i < length; ++i) {
         if (glyphs[i] == properties->wgDefault ||
             (glyphs[i] == properties->wgInvalid &&
              glyphs[i] != properties->wgBlank))   <===== UMR reported here.
             return true;
     }

     return false;
}

==============================================
Transformation 1
==============================================

// The following transformation is identical in meaning to the
// original code. I moved the sub-expressions into separate functions to
// get more meaningful callstacks. This still reports UMRs
//  (in test1 and test2), but makes the callstack more specific.

static bool test1(int i, WORD* glyphs, SCRIPT_FONTPROPERTIES* properties) {
   return glyphs[i] == properties->wgDefault;  <===== UMR reported here
}

static bool test2(int i, WORD* glyphs, SCRIPT_FONTPROPERTIES* properties) {
   return glyphs[i] == properties->wgInvalid;  <===== UMR reported here
}

static bool test3(int i, WORD* glyphs, SCRIPT_FONTPROPERTIES* properties) {
   return glyphs[i] != properties->wgBlank;
}

static bool ContainsMissingGlyphs(WORD *glyphs,
                                   int length,
                                   SCRIPT_FONTPROPERTIES* properties)
{
     for (int i = 0; i < length; ++i) {
         if (test1(i, glyphs, properties) ||
             (test2(i, glyphs, properties) &&
              test3(i, glyphs, properties)))
             return true;
     }
     return false;
}

==============================================
Transformation 2
==============================================

// Now for the interesting part. I rewrote test1 to use explicit WORD  
temporaries,
// hoping to see which of the WORD accesses purportedly gives a BYTE UMR.
// Instead what happened is the UMR no longer reproduces!

static bool test1(int i, WORD* glyphs, SCRIPT_FONTPROPERTIES* properties) {
   WORD g = glyphs[i];
   WORD x = properties->wgDefault;
   return g == x;
   // ORIGINAL:
   // return glyphs[i] == properties->wgDefault;
}


Following is a dump of the generated assembly code, to compare how the  
instructions
differ for these two versions of test1().


==============================================
test1 {v1, pre-instrumented}
==============================================

// (this is the version that gives UMR)
static bool test1(int i, WORD* glyphs, SCRIPT_FONTPROPERTIES* properties) {
   return glyphs[i] == properties->wgDefault;
}

    24 00b3ec50 55              push    ebp
    24 00b3ec51 8bec            mov     ebp,esp
    25 00b3ec53 8b4508          mov     eax,dword ptr [ebp+8]
    25 00b3ec56 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
    25 00b3ec59 0fb71441        movzx   edx,word ptr [ecx+eax*2]
    25 00b3ec5d 8b4510          mov     eax,dword ptr [ebp+10h]
    25 00b3ec60 0fb74806        movzx   ecx,word ptr [eax+6]
    25 00b3ec64 33c0            xor     eax,eax
    25 00b3ec66 3bd1            cmp     edx,ecx
    25 00b3ec68 0f94c0          sete    al
    26 00b3ec6b 5d              pop     ebp
    26 00b3ec6c c3              ret

==============================================
test1 {v2, pre-instrumented}:
==============================================

// (this is the version that passes)
static bool test1(int i, WORD* glyphs, SCRIPT_FONTPROPERTIES* properties) {
   WORD g = glyphs[i];
   WORD x = properties->wgDefault;
   return g == x;
}

    24 00b3ec50 55              push    ebp
    24 00b3ec51 8bec            mov     ebp,esp
    24 00b3ec53 83ec08          sub     esp,8
    25 00b3ec56 8b4508          mov     eax,dword ptr [ebp+8]
    25 00b3ec59 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
    25 00b3ec5c 668b1441        mov     dx,word ptr [ecx+eax*2]
    25 00b3ec60 668955f8        mov     word ptr [ebp-8],dx
    26 00b3ec64 8b4510          mov     eax,dword ptr [ebp+10h]
    26 00b3ec67 668b4806        mov     cx,word ptr [eax+6]
    26 00b3ec6b 66894dfc        mov     word ptr [ebp-4],cx
    27 00b3ec6f 0fb755f8        movzx   edx,word ptr [ebp-8]
    27 00b3ec73 0fb745fc        movzx   eax,word ptr [ebp-4]
    27 00b3ec77 33c9            xor     ecx,ecx
    27 00b3ec79 3bd0            cmp     edx,eax
    27 00b3ec7b 0f94c1          sete    cl
    27 00b3ec7e 8ac1            mov     al,cl
    29 00b3ec80 8be5            mov     esp,ebp
    29 00b3ec82 5d              pop     ebp
    29 00b3ec83 c3              ret

==============================================
test1 {v1, post-instrumented}:
==============================================

// (this is the version that gives UMR)
static bool test1(int i, WORD* glyphs, SCRIPT_FONTPROPERTIES* properties) {
   return glyphs[i] == properties->wgDefault;
}

    24 019aa4d0 50              push    eax
    24 019aa4d1 b804000000      mov     eax,4
    24 019aa4d6 ff1544afdd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daf44) (02ddaf44)]
    24 019aa4dc 55              push    ebp
    24 019aa4dd 8bec            mov     ebp,esp
    25 019aa4df 8b4508          mov     eax,dword ptr [ebp+8]
    25 019aa4e2 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
    25 019aa4e5 50              push    eax
    25 019aa4e6 8d0441          lea     eax,[ecx+eax*2]
    25 019aa4e9 ff15b0aedd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daeb0) (02ddaeb0)]
    25 019aa4ef 0fb71441        movzx   edx,word ptr [ecx+eax*2]
    25 019aa4f3 8b4510          mov     eax,dword ptr [ebp+10h]
    25 019aa4f6 50              push    eax
    25 019aa4f7 8d4006          lea     eax,[eax+6]
    25 019aa4fa ff15b0aedd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daeb0) (02ddaeb0)]
    25 019aa500 0fb74806        movzx   ecx,word ptr [eax+6]
    25 019aa504 33c0            xor     eax,eax
    25 019aa506 3bd1            cmp     edx,ecx
    25 019aa508 0f94c0          sete    al
    26 019aa50b 50              push    eax
    26 019aa50c b808000000      mov     eax,8
    26 019aa511 ff1548afdd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daf48) (02ddaf48)]
    26 019aa517 5d              pop     ebp
    26 019aa518 c3              ret

***********************************************************************
* Note that when enabling IP and IP offsets, Purify claims the error
* occurred at "test1 + 0x20" (IP=ip=0x019AA4F0).
*
* Alas, this isn't actually a valid instruction boundary. The nearest
* real instruction is at IP=0x019AA4EF).
*
*   25 019aa4ef 0fb71441        movzx   edx,word ptr [ecx+eax*2]
*
***********************************************************************

==============================================
test1 {v2, post-instrumented}:
==============================================

// (this is the version that passes)
static bool test1(int i, WORD* glyphs, SCRIPT_FONTPROPERTIES* properties) {
   WORD g = glyphs[i];
   WORD x = properties->wgDefault;
   return g == x;
}

    24 019aa4d0 50              push    eax
    24 019aa4d1 b804000000      mov     eax,4
    24 019aa4d6 ff1544afdd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daf44) (02ddaf44)]
    24 019aa4dc 55              push    ebp
    24 019aa4dd 8bec            mov     ebp,esp
    24 019aa4df 83ec08          sub     esp,8
    24 019aa4e2 50              push    eax
    24 019aa4e3 b808000000      mov     eax,8
    24 019aa4e8 ff154cafdd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daf4c) (02ddaf4c)]
    25 019aa4ee 8b4508          mov     eax,dword ptr [ebp+8]
    25 019aa4f1 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
    25 019aa4f4 50              push    eax
    25 019aa4f5 6802000000      push    2
    25 019aa4fa 8d0441          lea     eax,[ecx+eax*2]
    25 019aa4fd ff15b4aedd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daeb4) (02ddaeb4)]
    25 019aa503 668b1441        mov     dx,word ptr [ecx+eax*2]
    25 019aa507 50              push    eax
    25 019aa508 6802000000      push    2
    25 019aa50d 8d45f8          lea     eax,[ebp-8]
    25 019aa510 ff15dcaedd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daedc) (02ddaedc)]
    25 019aa516 668955f8        mov     word ptr [ebp-8],dx
    26 019aa51a 8b4510          mov     eax,dword ptr [ebp+10h]
    26 019aa51d 50              push    eax
    26 019aa51e 6801000000      push    1
    26 019aa523 8d4006          lea     eax,[eax+6]
    26 019aa526 ff15b4aedd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daeb4) (02ddaeb4)]
    26 019aa52c 668b4806        mov     cx,word ptr [eax+6]
    26 019aa530 50              push    eax
    26 019aa531 6801000000      push    1
    26 019aa536 8d45fc          lea     eax,[ebp-4]
    26 019aa539 ff15dcaedd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daedc) (02ddaedc)]
    26 019aa53f 66894dfc        mov     word ptr [ebp-4],cx
    27 019aa543 0fb755f8        movzx   edx,word ptr [ebp-8]
    27 019aa547 0fb745fc        movzx   eax,word ptr [ebp-4]
    27 019aa54b 33c9            xor     ecx,ecx
    27 019aa54d 3bd0            cmp     edx,eax
    27 019aa54f 0f94c1          sete    cl
    27 019aa552 8ac1            mov     al,cl
    29 019aa554 ff1558afdd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daf58) (02ddaf58)]
    29 019aa55a 8be5            mov     esp,ebp
    29 019aa55c ff155cafdd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daf5c) (02ddaf5c)]
    29 019aa562 50              push    eax
    29 019aa563 b808000000      mov     eax,8
    29 019aa568 ff1548afdd02    call    dword ptr [test_shell!_tls_end  
<PERF> (test_shell+0x29daf48) (02ddaf48)]
    29 019aa56e 5d              pop     ebp
    29 019aa56f c3              ret


--
You received this message because you are listed in the owner
or CC fields of this issue, or because you starred this issue.
You may adjust your issue notification preferences at:
http://code.google.com/hosting/settings

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Chromium-bugs" group.
To post to this group, send email to chromium-bugs@googlegroups.com
To unsubscribe from this group, send email to 
chromium-bugs+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/chromium-bugs?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to