简体   繁体   中英

C++ - How can I find out where the current thread was created?

I'm working on a huge C++ MFC GUI app using Visual Studio 2010 that's got tons of code the I'm unfamiliar with.

There's a thread that's being spawned way too many times, and I'm not sure where it's being spawned as there's lots of code that spawns this thread. Also, there are many creating points in the code for the same thread. I need to find which creating point started the current thread function.

How can I find where the thread was created in Visual Studio?

Note: I couldn't see where the thread was created in call stack window.

If its possible then make a macro definition for a function which is used for creating threads, then once it is created store thread id/handle in some map which will contain pairs of type: [ThreadID] -> [ __FILE__+__LINE__ ] . This will allow you to check inside your thread where it was created.

a more advanced aproach is to use api hooks, but thats a lot of coding. So you can make use of api hooking with http://codefromthe70s.org/mhook22.aspx and hook CreateThread. When your custom CreateThread function gets executed then you can execute original CreateThread and using its returned handle update a map as in first paragraph. The problem is that you will have to store callstack data to find where this call was executed. You could use http://www.codeproject.com/Articles/11132/Walking-the-callstack for that.

Even with first solution, you might find that __FILE__+__LINE__ does not give you enough information, and a callstack is a must.


I made a small test app with mhook - below is some code that might be useful:

typedef HANDLE(WINAPI *CreateThread_t)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD);
CreateThread_t fCreateThread = (CreateThread_t)GetProcAddress(LoadLibrary(L"Kernel32.dll"), "CreateThread");

HANDLE
WINAPI
MyCreateThread(
  _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_ SIZE_T dwStackSize,
  _In_ LPTHREAD_START_ROUTINE lpStartAddress,
  _In_opt_ __drv_aliasesMem LPVOID lpParameter,
  _In_ DWORD dwCreationFlags,
  _Out_opt_ LPDWORD lpThreadId
  )
{
  HANDLE hret = fCreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId);
  // Here you can add thread entry for hret with current callstack.
  // You will probably want to create this thread suspended, to make
  // sure it wont get executed before map gets updated. Resume it after
  // map update.
  //if (lpStartAddress == MyThreadProcToMonitor) {
    // log things
  //}
  return hret;
}

int main() {
// This will hook create thread
  Mhook_SetHook((PVOID*)&fCreateThread, MyCreateThread);

  // App logic here

  Mhook_Unhook((PVOID*)&fCreateThread);
}

如果允许您稍微更改代码,则可以用一个宏替换线程启动调用,该宏还将记录__FILE____FILE__ __LINE__和线程ID,以便您可以跟踪启动。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM