0

I'm trying to write a memory tracker for my Windows app. I've already finished a prototype using Detours. I hooked HeapAlloc, HeapReAlloc, HeapFree, HeapDestroy and output some logs for me to check. However there's something wrong.

Here's my sample code:

void thread_foo()
{
    while(1)
    {
        void* tempPtr = HeapAlloc(GetProcessHeap(), 0, 3);
        Sleep(50);
    }
}

int main()
{
    std::thread tobj(thread_foo);
    int size = 16;
    tobj.join();
}

And here's my tracking output (first 32 lines, format as ALLOC/FREE/REALLOC/DESTROY: timestamp, call stack hash, heap pointer, flags, size, result pointer):

ALLOC:2736795824738, -592122872, 0000019110690000, 0, 256, 000001911069E130
ALLOC:2736795825084, 1232708493, 0000019110690000, 0, 16, 000001911069F0A0
ALLOC:2736795825225, -929256262, 0000019110690000, 0, 56, 000001911069FAF0
ALLOC:2736795825284, -929523462, 0000019110690000, 0, 2, 000001911069FBF0
ALLOC:2736795825323, 151458640, 0000019110690000, 0, 2, 000001911069FBF0
ALLOC:2736795825369, -929340699, 0000019110690000, 0, 16, 000001911069F200
ALLOC:2736795825404, 1203567881, 0000019110690000, 0, 48, 000001911069F570
ALLOC:2736795825436, 1789431341, 0000019110690000, 8, 344, 000001911069FC10
ALLOC:2736795825511, -1394565794, 0000019110690000, 0, 1702, 000001911069FD70
ALLOC:2736795825573, 955998638, 0000019110690000, 0, 6, 000001911069E240
ALLOC:2736795825600, -958719147, 0000019110690000, 0, 2, 000001911069E260
ALLOC:2736795825625, 955994058, 0000019110690000, 8, 4, 000001911069E280
ALLOC:2736795825651, 1789431550, 0000019110690000, 8, 344, 000001911069E2A0
ALLOC:2736795825677, -1394565585, 0000019110690000, 0, 1702, 000001911069FD70
ALLOC:2736795825714, 955998680, 0000019110690000, 0, 6, 000001911069E280
ALLOC:2736795825736, 122263169, 0000019110690000, 0, 2, 000001911069E240
ALLOC:2736795825761, 1203256005, 0000019110690000, 8, 512, 000001911069E400
ALLOC:2736795825786, 955996289, 0000019110690000, 8, 4, 000001911069E610
ALLOC:2736795825810, 1789433781, 0000019110690000, 8, 344, 000001911069FC10
ALLOC:2736795825834, -1394563354, 0000019110690000, 0, 1702, 000001911069FD70
ALLOC:2736795825868, 956000911, 0000019110690000, 0, 6, 000001911069E610
ALLOC:2736795825893, 1203615483, 0000019110690000, 0, 16, 000001911069F140
ALLOC:2736795825921, 1232708730, 0000019110690000, 0, 16, 000001911069F160
ALLOC:2736795825945, -929316070, 0000019110690000, 0, 16, 000001911069F260
ALLOC:2736795825968, 1232708941, 0000019110690000, 0, 16, 000001911069F1A0
ALLOC:2736795825990, -929340251, 0000019110690000, 0, 16, 000001911069F2A0
ALLOC:2736795826013, 1232709165, 0000019110690000, 0, 16, 000001911069F0C0
ALLOC:2736795826033, -929340027, 0000019110690000, 0, 16, 000001911069F100
ALLOC:2736795826066, 151797360, 0000019110690000, 0, 16, 000001911069F120
ALLOC:2736795826106, -929229531, 0000019110690000, 0, 16, 000001911069F2C0
ALLOC:2736795826131, 1203787877, 0000019110690000, 0, 96, 000001911069E240
ALLOC:2736795826158, 1789651341, 0000019110690000, 8, 344, 000001911069FD70

The problem is the 4th and 5th line, as we can see, get the same pointer. There's no HeapFree or HeapDestroy between them. And these 2 HeapAllocs are not my calls, I can determine it by the size. I assume they are related with std::thread. And they are not the only same pair. 9th, 14th, 20th, 32th lines are also same.

If removing thread-related codes, by simply calling thread_foo() in main(), everything looks good again.

Does anybody get any idea for it?

P.S. If there's anybody caring about the hooking code, it's just based on https://github.com/microsoft/Detours/blob/master/samples/tracemem/trcmem.cpp

I added hooking HeapReAlloc, HeapFree, HeapDestroy and collecting logs to file.

ALL CLEAR! ALL CLEAR!

I found why. The reason is that although I hooked HeapFree, all memory freed by delete or free() didn't call my wrapped HeapFree. I don't know why, but that's the fact. Now I also hooked CRT free(), the prevously hidden free message comes out.

Therefore, I changed the title of this question. Hoped anyone has any clue about it.

Zimian
  • 1
  • 1
  • I don't know the detours library, but one possible problem with your code is that the `join()` will never return so the rest of the code in `main()` should be removed by any decent optimizer. – Ted Lyngmo Jan 03 '20 at 14:13
  • 1
    @TedLyngmo thanks, you are right about this part. I'll remove those codes to avoid the ambiguity. – Zimian Jan 03 '20 at 14:16
  • 1
    We need to see the code for your hook. Most likely, there is something wrong with it. Is it threadsafe, for example? – Paul Sanders Jan 03 '20 at 14:22
  • @PaulSanders In Detours 4.0.1, there's a sample called "tracemem", my hooking code is based on that one, nothing special I think. – Zimian Jan 06 '20 at 12:27

1 Answers1

0

Pretty much every modern C++ implementation will recycle small allocations internally, without involving the OS. Involving the OS takes a certain time overhead, and the few bytes saved just don't justify that.

MSalters
  • 173,980
  • 10
  • 155
  • 350