New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
False pos: 80 byte leak from plfCreateLOCALFONT on Win7 #733
Comments
From bruen...@google.com on January 04, 2012 14:28:35 I have seen reference to plfCreateLOCALFONT in two places
28 total, here's one: Error 0 GDI32.dll!plfCreateLOCALFONT1 GDI32.dll!CreateFontIndirectExW2 GDI32.dll!CreateFontIndirectW3 USER32.dll!CreateDlgFont4 USER32.dll!InternalCreateDialog5 USER32.dll!CreateDialogIndirectParamAorW6 USER32.dll!CreateDialogParamW7 InitSciCalc8 WinMain
Error |
From rnk@google.com on January 10, 2012 12:33:41 Fixed in r696 . |
From rnk@google.com on January 27, 2012 11:32:19 Should say "suppessed in r696 ". It would be interesting to implement something to interpret this backwards linked list in an array as reachable. Labels: -Priority-Medium Priority-Low |
From bruen...@google.com on May 13, 2013 10:56:38 A win8 app_suite_tests Msgbox leak looks similar to the one here so I'm going to expand that suppression: Error 0 replace_RtlAllocateHeap+0x0 [c:\derek\drmemory\git\src\common\alloc_replace.c:2878](0x02b75ff0 <drmemorylib.dll+0x175ff0)1 GDI32.dll!CreateFontIndirectExW+0x152 (0x7666018e <GDI32.dll+0x5018e>)2 GDI32.dll!CreateFontIndirectW+0x5e (0x7666013e <GDI32.dll+0x5013e>)3 GDI32.dll!CacheFontLinkingData+0x212 (0x7662e310 <GDI32.dll+0x1e310>)4 GDI32.dll!IsFontRegLinked+0x23 (0x7662df89 <GDI32.dll+0x1df89>)5 GDI32.dll!LoadFont +0x3a93 (0x7662e0dd <GDI32.dll+0x1e0dd>)6 GDI32.dll!FindOrCreateFaceCache+0xb92 (0x7662a625 <GDI32.dll+0x1a625>)7 GDI32.dll!FindOrCreateSizeCacheWithoutRealizationID+0x75 (0x766292e5 <GDI32.dll+0x192e5>)8 GDI32.dll!FindOrCreateSizeCacheUsingRealizationID+0x8f58 (0x7662924d <GDI32.dll+0x1924d>)9 GDI32.dll!UpdateCache+0x2c (0x766203ef <GDI32.dll+0x103ef>)#10 GDI32.dll!ScriptCheckCache+0x526e (0x766203a8 <GDI32.dll+0x103a8>) Owner: --- |
From rnk@google.com on January 04, 2012 16:35:58
I only seem to get this error report on my workstation. It started happening a few weeks before the holidays, and since then I've been unable to run the drmemory suite and have been relying on the bots to run the full suite.
Here is the leak:
Dr.MError#1
: POSSIBLE LEAK 80 direct bytes 0x00fc34b0-0x00fc3500 + 0 indirect bytesDr.M# 0 GDI32.dll!plfCreateLOCALFONTDr.M# 1 GDI32.dll!CreateFontIndirectExWDr.M# 2 GDI32.dll!CreateFontIndirectWDr.M# 3 UxTheme.dll!CInternalNonclientMetrics::AcquireDr.M# 4 UxTheme.dll!NcGetNonclientMetricsDr.M# 5 UxTheme.dll!AcquireNcThemeMetricsDr.M# 6 UxTheme.dll!OnHooksEnabledDr.M# 7 USER32.dll!InitUserApiHookDr.M# 8 USER32.dll!__ClientLoadLibraryDr.M# 9 ntdll.dll!KiUserCallbackDispatcherDr.M#10
sophos_detoured.dll!Detoured +0x38 (0x6fa09579 <sophos_detoured.dll+0x9579>)Dr.M#11
sophos_detoured.dll!spmaa_finalise2 +0x1ca6 (0x6fa19267 <sophos_detoured.dll+0x19267>)I ran with a higher verbosity to see who points to it:
defined range 0x01200000-0x01381000
(0x0120b830 points to mid-chunk 0x02a70d00 in 0x02a70a20-0x02a71220)
(0x0120b980 points to mid-chunk 0x02a70b60 in 0x02a70a20-0x02a71220)
(0x01215838 points to mid-chunk 0x00fc34f8 in 0x00fc34b0-0x00fc3500) *** our chunk
(0x01215a00 points to mid-chunk 0x00fc34f0 in 0x00fc34b0-0x00fc3500) *** our chunk
...
defined range 0x76be0000-0x76be1000
(0x76be0030 points to mid-chunk 0x00fc34e8 in 0x00fc34b0-0x00fc3500) *** our chunk
is_vtable 0x00fc34e0: 2, 3
The chunk itself:
defined range 0x00fc34b0-0x00fc3500
(0x00fc34b8 points to start of its own chunk 0x00fc34b0-0x00fc3500)
(0x00fc34c0 points to middle 0x00fc34b8 of its own chunk 0x00fc34b0-0x00fc3500)
(0x00fc34c8 points to middle 0x00fc34c0 of its own chunk 0x00fc34b0-0x00fc3500)
(0x00fc34d0 points to middle 0x00fc34c8 of its own chunk 0x00fc34b0-0x00fc3500)
(0x00fc34d8 points to middle 0x00fc34d0 of its own chunk 0x00fc34b0-0x00fc3500)
(0x00fc34e0 points to middle 0x00fc34d8 of its own chunk 0x00fc34b0-0x00fc3500)
(0x00fc34e8 points to middle 0x00fc34e0 of its own chunk 0x00fc34b0-0x00fc3500)
So, it looks like there is a global that points to the last element of this array, and the array itself is basically a linked list, where each node is 8 bytes and points to a node 8 bytes prior.
This seems to be exactly what GDI32.dll!plfCreateLOCALFONT does. Here are the basic blocks:
in event_basic_block(tag=0x76b95b4d)
new basic block @0x76b95b4d == GDI32.dll!plfCreateLOCALFONT
TAG 0x76b95b4d
+0 L3 8b ff mov %edi -> %edi
+2 L3 55 push %ebp %esp -> %esp 0xfffffffc(%esp)
+3 L3 8b ec mov %esp -> %ebp
+5 L3 56 push %esi %esp -> %esp 0xfffffffc(%esp)
+6 L3 8b 35 30 00 be 76 mov 0x76be0030 -> %esi
+12 L3 85 f6 test %esi %esi
+14 L3 0f 84 b2 02 00 00 jz $0x76b95e13
END 0x76b95b4d
in event_basic_block(tag=0x76b95e13)
new basic block @0x76b95e13 == GDI32.dll!plfCreateLOCALFONT
TAG 0x76b95e13
+0 L3 64 a1 18 00 00 00 mov %fs:0x18 -> %eax
+6 L3 8b 40 30 mov 0x30(%eax) -> %eax
+9 L3 6a 50 push $0x00000050 %esp -> %esp 0xfffffffc(%esp) # 80 bytes
+11 L3 6a 00 push $0x00000000 %esp -> %esp 0xfffffffc(%esp)
+13 L3 ff 70 18 push 0x18(%eax) %esp -> %esp 0xfffffffc(%esp)
+16 L3 ff 15 a8 01 b9 76 call 0x76b901a8 %esp -> %esp 0xfffffffc(%esp)
END 0x76b95e13
**** Malloc of 0x00fc34b0 happens here
alloc_hook retaddr=0x76b95e29
found new retaddr: call to RtlAllocateHeap from 0x76b95e29 non-instru
entering alloc routine 0x7765e026 RtlAllocateHeap indirect rec=0 adj=0 post-retaddr
alloc type: 4
malloc-pre heap=0x00f60000 size=0x50 flags=0x0
in event_basic_block(tag=0x76b95e29)
new basic block @0x76b95e29 == GDI32.dll!plfCreateLOCALFONT
TAG 0x76b95e29
+0 L3 8b f0 mov %eax -> %esi
+2 L3 6a 08 push $0x00000008 %esp -> %esp 0xfffffffc(%esp)
+4 L3 85 f6 test %esi %esi
+6 L3 74 09 jz $0x76b95e3a # Check for null pointer
END 0x76b95e29
in event_basic_block(tag=0x76b95e31)
new basic block @0x76b95e31 == GDI32.dll!plfCreateLOCALFONT
TAG 0x76b95e31
+0 L3 83 26 00 and $0x00000000 (%esi) -> (%esi)
+3 L3 83 c6 08 add $0x00000008 %esi -> %esi
+6 L3 58 pop %esp (%esp) -> %eax %esp # eax is 0x08 from earlier push
+7 L3 eb 0a jmp $0x76b95e44
END 0x76b95e31
in event_basic_block(tag=0x76b95e44)
new basic block @0x76b95e44 == GDI32.dll!plfCreateLOCALFONT
TAG 0x76b95e44
+0 L3 8d 4e f8 lea 0xfffffff8(%esi) -> %ecx # Gets addr of prev node
+3 L3 89 0e mov %ecx -> (%esi) # Stores to probable "next" field
+5 L3 83 c6 08 add $0x00000008 %esi -> %esi
+8 L3 48 dec %eax -> %eax
+9 L3 75 f5 jnz $0x76b95e44
END 0x76b95e44
in event_basic_block(tag=0x76b95e4f)
new basic block @0x76b95e4f == GDI32.dll!plfCreateLOCALFONT
TAG 0x76b95e4f
+0 L3 8d 46 f8 lea 0xfffffff8(%esi) -> %eax
+3 L3 e9 0c fd ff ff jmp $0x76b95b63
END 0x76b95e4f
in event_basic_block(tag=0x76b95b63)
new basic block @0x76b95b63 == GDI32.dll!plfCreateLOCALFONT
TAG 0x76b95b63
+0 L3 a3 30 00 be 76 mov %eax -> 0x76be0030 # Store final element to global
+5 L3 85 f6 test %esi %esi
+7 L3 74 09 jz $0x76b95b75
END 0x76b95b63
in event_basic_block(tag=0x76b95b6c)
new basic block @0x76b95b6c == GDI32.dll!plfCreateLOCALFONT
TAG 0x76b95b6c
+0 L3 8b 45 08 mov 0x08(%ebp) -> %eax
+3 L3 83 66 04 00 and $0x00000000 0x04(%esi) -> 0x04(%esi)
+7 L3 89 06 mov %eax -> (%esi)
+9 L3 8b c6 mov %esi -> %eax
+11 L3 5e pop %esp (%esp) -> %esi %esp
+12 L3 5d pop %esp (%esp) -> %ebp %esp
+13 L3 c2 04 00 ret $0x00000004 %esp (%esp) -> %esp
END 0x76b95b6c
I could add a suppression for plfCreateLOCALFONT, since it seems like a small leaf routine, but it's possible that it could allocate things that a user is forgetting to free.
Alternatively we could try to handle this by following pointers from mid-chunk pointers. I don't know how many false negatives that might create, though.
I'm going to suppress leaks from plfCreateLOCALFONT for now, unless anyone objects.
If anyone else could try running tests/hello.exe and searching the logs for plfCreateLOCALFONT, that would be useful information.
Original issue: http://code.google.com/p/drmemory/issues/detail?id=733
The text was updated successfully, but these errors were encountered: