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 -~----------~----~----~----~------~----~------~--~---