Stackwalk64 - probleme

Acest forum este dedicat intrebarilor de Windows API, folosing C/C++
Post Reply
Grunt
Junior
Junior
Posts: 3
Joined: 31 Aug 2009, 23:16
Judet: Iaşi

Stackwalk64 - probleme

Post by Grunt » 26 Jun 2010, 20:45

Salut.

Trebuie sa afisez un stack trace pentru un proces care genereaza o exceptie. Asta trebuie sa se intample intr-un nou proces. Folosesc dbghelp pentru toata chestia, si am dat de o fundatura. Este setat un UnhandledExceptionFilter intr-un dll (incarcat de procesul gazda), iar functia mea porneste procesul nou cu CreateProcess apoi face WaitForSingleObject pe el. Procesoul nou se ataseaza la cel vechi, de unde iau contextul thread-ului sau (ca are unul singur), apoi pornesc StackWalk64():

Code: Select all

SuspendThread(hThread);

ZeroMemory(&context, sizeof(context));
context.ContextFlags = CONTEXT_FULL;
if (!GetThreadContext(hThread, &context))
{
    ResumeThread(hThread);
    return;
}
// ... alte initializari, bla bla bla


for (int i = 0; /*nothing*/; i++)
{
    if (!StackWalk64(
        IMAGE_FILE_MACHINE_I386,
        m_process.GetHandle(),
        hThread,
        &m_currentFrame,
        &context,
        &Callbacks::ReadProcessMemory,
        &Callbacks::SymFunctionTableAccess64,
        &Callbacks::SymGetModuleBase64,
        NULL))
    {
        break;
    }
    // ... do stuff
}
Codul merge ok, pana la un punct. La un moment dat, se opreste la ntdll.dll!KiUserExceptionDispatcher(). Din cate am citit, functia asta e apelata din kernel mode, si trimite exceptia inapoi catre user mode, ceea ce cred ca e motivul pentru care StackWalk64 nu poate continua. Practic, stack trace-ul meu arata asa:

Code: Select all

ntdll.dll!KiFastSystemCallRet() [unknown file]
ntdll.dll!NtWaitForSingleObject() [unknown file]
kernel32.dll!WaitForSingleObjectEx() [unknown file]
kernel32.dll!WaitForSingleObject() [unknown file]
kdeui.dll!KCrash::startProcess() kcrash.cpp@448
kdeui.dll!KCrash::defaultCrashHandler() kcrash.cpp@414
kdeui.dll!KCrash::win32UnhandledExceptionFilter() kcrash.cpp@478
kernel32.dll!UnhandledExceptionFilter() [unknown file]
kernel32.dll!BaseProcessStart() [unknown file]
kernel32.dll!_except_handler3() [unknown file]
ntdll.dll!ExecuteHandler2() [unknown file]
ntdll.dll!ExecuteHandler() [unknown file]
ntdll.dll!KiUserExceptionDispatcher() [unknown file]
Si nu vrea sa continue. Stack trace-ul pe care il obtin nu imi ofera nici o informatie in legatura cu originea exceptiei, vad doar ce se intampla dupa ce ajunge inapoi in user mode. StackWalk64 sigur esueaza, pentru ca dupa for am inca un context valid si daca o mai apelez o data pe acelasi context, returneaza FALSE - insa o alta problema e ca nu stiu care e cauza (documentatia spune ca in general nu seteaza LastError, si asa si e - GetLastError() returneaza 0).

Eu mai am un CONTEXT in kdeui.dll, pe care il preiau de la parametrul dat win32UnhandledExceptionFilter (_EXCEPTION_POINTERS). Folosesc memorie shared ca sa il pot accesa din procesul meu. Daca dau ca parametrul contextul asta la apelul StackWalk64, pot sa vad stica corecta, pana in punctul in care apare exceptia, si nu mai departe. Deci am doua solutii, fiecare din ele rezolvand problema doar pe jumatate.

Are cineva vreo sugestie?



Viorel
Microsoft MVP
Microsoft MVP
Posts: 291
Joined: 13 Jul 2007, 12:26

Re: Stackwalk64 - probleme

Post by Viorel » 26 Jun 2010, 22:27

Cum se afișează stiva dacă se execută StackWalk64 direct din locul unde a fost interceptată exceptia, folosind contextul transmis ca parametru și fără a lansa alte procese?

Grunt
Junior
Junior
Posts: 3
Joined: 31 Aug 2009, 23:16
Judet: Iaşi

Re: Stackwalk64 - probleme

Post by Grunt » 27 Jun 2010, 02:24

Teoretic ar trebui sa fie aceeasi chestie ca si pentru cazul cu memorie shared. Mai greu insa sa fac asta de acolo, pentru ca nu pot sa iau contextul thread-ului curent fara inline assembly, sau creand alt thread pentru asta.

Si oricum... eu trebuie sa fac asta dintr-un proces separat.

Post Reply