Skip to content
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

CreateToolhelp32Snapshot is slow when there are a lot of threads #885

Open
char101 opened this issue Oct 5, 2016 · 4 comments
Open

CreateToolhelp32Snapshot is slow when there are a lot of threads #885

char101 opened this issue Oct 5, 2016 · 4 comments

Comments

@char101
Copy link

char101 commented Oct 5, 2016

Problem description

I found opening new tab in ConEmu become slow after a prolonged use. This is an issue I initially found with mridgers/clink#420. I suspect the slowness in opening a new tab in ConEmu could be caused by CreateToolhelp32Snapshot too since I found a lot of call to this function in ConEmu sources.

For example

#include <Windows.h>
#include <TlHelp32.h>
#include <stdio.h>
#include <time.h>

int main()
{
    clock_t start = clock();
    HANDLE th32 = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (th32 == INVALID_HANDLE_VALUE)
    {
        printf("Invalid handle");
    }
    else
    {
        THREADENTRY32 te = { sizeof(te) };
        BOOL ok = Thread32First(th32, &te);
        int nThread = 0;
        while (ok != FALSE)
        {
            ++nThread;
            ok = Thread32Next(th32, &te);
        }
        printf("%d threads, %.2f ms", nThread, 1000.0 * (clock() - start) / CLOCKS_PER_SEC);
    }

    return 0;
}

In my current OS:

> snapshot
3041 threads, 274.00 ms

And this function needs to be called at least twice, that results in at least 500ms delay when opening a new tab.

Is it possible to replace some of the call to CreateToolhelp32Snapshot for suspending threads with NtSuspendProcess. Also looking at the source of NtSuspendProcess, it seems possible to enumerate the threads of a process without enumerating all the threads in the system.

@Maximus5
Copy link
Owner

Maximus5 commented Oct 5, 2016

First of all you should search for TH32CS_SNAPTHREAD instead of CreateToolhelp32Snapshot.
You'll see very few cases which are conditional. Generally speaking, enumeration of threads would be called on Win+G only AFAIR.

To check the bottle neck you can simply run the following

ConEmu -basic -log -run cmd /D

@Maximus5
Copy link
Owner

Maximus5 commented Oct 5, 2016

And post link to LogFiles here

@char101
Copy link
Author

char101 commented Oct 6, 2016

Here are the logfiles. Doesn't minhook uses CreateToolhelp32Snapshot to suspend/resume the target process threads before/after hooking?

ConEmu-con-195456.log.txt
ConEmu-gui-13484.log.txt
ConEmu-srv-195456.log.txt

@Maximus5
Copy link
Owner

Maximus5 commented Oct 6, 2016

I use my fork of minhooks, it doesn't use CreateToolhelp32Snapshot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants