Вход на сайт

Просмотр новости

Найдите то, что Вас интересует

No, really, you need to pass all unhandled messages to DefWindowProc, part 2

Дата публикации: 24-09-2026 14:00:00

Another example to add to the list.
The post No, really, you need to pass all unhandled messages to DefWindowProc, part 2 appeared first on The Old New Thing.


Основное содержимое страницы с новостью.

A customer reported a memory leak in Windows that occurred when they called Register­Drag­Drop followed by Revoke­Drag­Drop. They included a time travel trace of a sample program that demonstrated the problem. (Though for some reason, they didn’t include the program itself; just the time travel trace.)

Now, it is strange that there would be a memory leak if you call Register­Drag­Drop followed by Revoke­Drag­Drop, seeing as this pattern is used heavily by thousands of applications, including many parts of Windows itself, so if there were a memory leak inherent in the pattern, you’d think it’d have been reported by now.

I suspected that there was something special about their sample program.

Some time ago, I noted that No, really, you need to pass all unhandled messages to DefWindowProc. And that was the source of the problem.

Debugging through the time travel trace showed that yes, they did call Register­Drag­Drop, and then they did call Revoke­Drag­Drop. But there’s more going on. When the window receives a WM_DESTROY message, it cleans up all its state. And for any messages that arrive after WM_DESTROY, the window procedure goes looking for its special state and doesn’t see it, so it gives up and just returns 0 without passing the message to Def­Window­Proc.

Oops.

If the window procedure can’t figure out what to do, it should pass all messages to Def­Window­Proc. In this case, it’s important because some of those messages are cleanup messages, and one of the things those cleanup messages do is free the last few fragments of memory still hanging around.

Bonus chatter: But if I register a drop target, and then revoke it, shouldn’t the revoke free all the memory that was allocated by the register call?

There’s no requirement that registering something and then unregistering it will immediately free all the memory associated with the registration. The system is allowed to cache stuff that it thinks will be needed again.

In this case, what happened is that the Register­Drag­Drop function uses an infrastructure that is shared by many components. That infrastructure is created and attached to the window the first time anybody needs it, and it is cleaned up when the window is destroyed. The memory isn’t leaked. It’s just cached on the window, waiting to be used by another operation. And the cache is destroyed when the window is destroyed.

But it assumes that you give Def­Window­Proc a chance to do that cleanup.

Author

Raymond Chen

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

Схожие новости

#Наименование новостиТональностьИнформативностьДата публикации
1Debugging walkthrough: Access violation on nonsense instruction, episode 307.8925-09-2026
2If somebody tries to hot-patch an already-hot-patched function, how do they avoid conflicts?012.9705-10-2026
3As a general rule, calling product support while drunk is not recommended04.5629-09-2026
4How can undefined opcodes ud0 and ud1 have parameters? How undefined were they?08.607-10-2026
5Windows on Itanium also provided for hot-patching, in an even simpler way010.201-10-2026
6Why is there no Windows hot-patching support for other architectures like 32-bit ARM and MIPS?09.0602-10-2026
7Why does the compiler sometimes use ud2 and sometimes int 3 for code that shouldn’t execute?07.706-10-2026
8Windows on AArch64 also provides for hot-patching, but it’s much simpler than on x86012.7730-09-2026
9C++ reminder: Function-local static variables are initialized only once, even if it looks like they get initialized multiple times05.9228-09-2026

Классификация: . Схожих патентов: 0. Схожих новостей: 9. Тональность: 0. Информативность: 5.84. Источник: blogs.msdn.microsoft.com.