Откуда С++ дебаггер берет информацию для графы "Location" в окошке "T

Тема в разделе "WASM.WIN32", создана пользователем Asmodaeous, 27 авг 2008.

  1. Asmodaeous

    Asmodaeous New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    5
    ...или "Откуда С++ дебаггер берет информацию для графы "Location" в окошке "Threads""

    Здравствуйте!

    Есть задача: узнать, какие подпрограммы выполняют все треды текущщего процесса.
    Используя tlhelp32, написал такой код:

    Код (Text):
    1. THREADENTRY32 threadEntry;
    2. memset (&threadEntry, 0, sizeof (THREADENTRY32));
    3. threadEntry.dwSize = sizeof (THREADENTRY32);
    4. HANDLE hSnapShot = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, 0);
    5.  
    6. if ((hSnapShot != INVALID_HANDLE_VALUE) && (Thread32First (hSnapShot, &threadEntry)))
    7. {
    8.     DWORD currPId = GetCurrentProcessId ();
    9.     DWORD currTId = GetCurrentThreadId ();
    10.     do
    11.     {
    12.         if (threadEntry.th32OwnerProcessID == currPId)
    13.         {
    14.             // в threadEntry лежит инфа про текущщий тред
    15.             int z = 0;
    16.         }
    17.     }
    18.     while (Thread32Next (hSnapShot, &threadEntry));
    19. }
    20. CloseToolhelp32Snapshot (hSnapShot);
    THREADENTRY32 имеет такие поля:

    Код (Text):
    1. typedef struct tagTHREADENTRY32{
    2.     DWORD dwSize;
    3.     DWORD cntUsage;
    4.     DWORD th32ThreadID;
    5.     DWORD th32OwnerProcessID;
    6.     LONG  tpBasePri;
    7.     LONG  tpDeltaPri;
    8.     DWORD dwFlags;
    9.     DWORD th32AccessKey;
    10.     DWORD th32CurrentProcessID;
    11. } THREADENTRY32;
    но не имеет "CurrentAddress" или чего-то похожего((

    Можно ли у винды узнать про этот тред чего-нибудь подробнее, используя например его th32ThreadID ? Си-шный дебаггер же узнаёт...

    Спасибо всем ответившим.
     
  2. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    С отладчиком все просто, т.к. ему по WaitForDebugEvent передаются соотв. структуры CREATE_PROCESS_DEBUG_INFO и CREATE_THREAD_DEBUG_INFO, содержащие lpStartAddress
     
  3. blast

    blast New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2008
    Сообщения:
    170
    Если имеется ввиду Eip потока, то NtGetContextThread.
     
  4. Asmodaeous

    Asmodaeous New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    5
    leo
    А кто ему их передает? Сама программа, или он-таки лезет через виндовые функции к ее структурам и выдает их внутренности?

    Отладчик же может показывать другие потоки, "застывшие" на выполнении всяких расчетов, а не на WaitForSomething
     
  5. Asmodaeous

    Asmodaeous New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    5
    blast
    Супер!!! А под младшие винды (до 2000) что-нибудь подобное есть?
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Asmodaeous
    Через WaitForDebugEvent винда информирует отладчик о создании\закрытии процесса и каждого из его потоков (кроме основного, инфа о котором передается вместе с инфой о процессе), о загрузке\выгрузке каждой из dll и обо всех исключениях, возникающих в программе. Поэтому отладчик только и делает, что крутит в цикле WaitForDebugEvent и обрабатывает собой же организованные исключения int1 и int3 :)

    PS: если лезть в native апи, то можно заюзать NtGetInformationThread для получения стартового адреса, а если нужен "хоть какой" примерный адрес, то можно и по GetThreadContext
     
  7. blast

    blast New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2008
    Сообщения:
    170
    Asmodaeous
    этот сервис есть во всех виндах)
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Asmodaeous
    Надеюсь ты понимаешь, что GetThreadContext может выдать адрес не только внутри ThreadProc, но и в любой системной dll в зависимости от того, где будет находится поток в момент вызова. А упомянутый тобой дебаггер все таки выдает не текущий, а стартовый адрес потока (EntryPoint для основного и ThreadProc для прочих)
     
  9. Asmodaeous

    Asmodaeous New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    5
    blast
    А какой .h надо включать в проект? А то у меня на Embedded VC 4 не компилится((

    leo
    Извините??..
    А вот если такую программу тормозить на строчке Sleep(0) и смотреть в дебаггере инфу о других трех потоках этого процесса, то адрес , который они выполняют, часто будет разным))
    Код (Text):
    1. DWORD WINAPI NewThreadRoutine (LPVOID lpParameter)
    2. {
    3.     int z;
    4.     while (1)
    5.     {
    6.         z += 1;
    7.         z += 2;
    8.         z += 3;
    9.     }
    10.     return 0;
    11. }
    12.  
    13. ///////////////////////////////////////////////////////////////////////////////
    14. int main(int argc, char* argv[])
    15. {
    16.     for (int i = 0; i < 3; i++)
    17.     {
    18.         HANDLE h = CreateThread(NULL, NULL, NewThreadRoutine, 0, CREATE_SUSPENDED, NULL);
    19.         ResumeThread (h);
    20.     }
    21.     while (1)
    22.         Sleep (0);
    23.     return 0;
    24. }
    Что адрес может находиться не только в выполняемой программе - конечно понимаю))
     
  10. Asmodaeous

    Asmodaeous New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2008
    Сообщения:
    5
    blast
    GetThreadContext меня спас!!!

    Спасибо всем! ))