简体   繁体   English

C ++-如何找出当前线程的创建位置?

[英]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. 我正在使用Visual Studio 2010开发一个巨大的C ++ MFC GUI应用程序,其中包含大量我不熟悉的代码。

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? 如何找到在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__ ] . 如果可能的话,请为用于创建线程的函数创建宏定义,然后在创建该函数后将线程ID /句柄存储在某些映射中,该映射将包含成对的类型:[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. 一个更高级的方法是使用api挂钩,但这就是很多代码。 So you can make use of api hooking with http://codefromthe70s.org/mhook22.aspx and hook CreateThread. 因此,您可以通过http://codefromthe70s.org/mhook22.aspx使用api挂钩并挂钩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. 当自定义的CreateThread函数执行后,您可以执行原始的CreateThread并使用其返回的句柄更新地图,如第一段所示。 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. 您可以为此使用http://www.codeproject.com/Articles/11132/Walking-the-callstack

Even with first solution, you might find that __FILE__+__LINE__ does not give you enough information, and a callstack is a must. 即使采用第一个解决方案,您也可能会发现__FILE__+__LINE__无法为您提供足够的信息,因此必须有一个调用栈。


I made a small test app with mhook - below is some code that might be useful: 我使用mhook制作了一个小型测试应用-以下是一些可能有用的代码:

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,以便您可以跟踪启动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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