Столкнувшись с этой проблемой, я взял StackWalker Йохена Кламбаха из CodeProject. Обновление: StackWalker теперь перешел на Codeplex . Определенно получите релиз Codeplex; включает в себя несколько обновлений и исправлений.
Он напечатает стек для вашего кода при сбое фильтра.
То, как я это сделал, было так: внутри OnAuthComplete в моем фильтре, где мой фильтр выполняет всю работу, я окружил логику попыткой ... кроме:
__try
{
dwRetval = DoRewrites(...);
}
__except ( ExcFilter(GetExceptionInformation()) )
{
}
И тогда ExcFilter определяется следующим образом:
extern "C" int ExcFilter(EXCEPTION_POINTERS *pExp)
{
MyLoggingStackWalker *sw = new MyLoggingStackWalker();
sw->ShowCallstack(GetCurrentThread(), pExp->ContextRecord);
return EXCEPTION_CONTINUE_SEARCH; // allow the process to crash
}
LoggingStackWalker является производным от StackWalker и переопределяет метод OnOutput для отправки этого вывода в файл журнала. Он также устанавливает путь поиска для файлов PDB, включая каталог, в котором находится DLL.
class MyLoggingStackWalker : public StackWalker
{
public:
MyLoggingStackWalker() : StackWalker()
{
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
// add the directory for the ISAPI DLL, to the search path for PDB files
this->m_szSymPath = (LPSTR) malloc(_MAX_PATH);
_splitpath_s(DllLocation, drive, _MAX_DRIVE, dir, _MAX_DIR, NULL, 0, NULL, 0);
_makepath_s(this->m_szSymPath, _MAX_PATH, drive, dir, NULL, NULL);
}
virtual void OnOutput(LPCSTR szText)
{
LogMessage((char*)szText);
StackWalker::OnOutput(szText);
}
};
Чтобы продемонстрировать это, я передаю неверный указатель на vscprintf в коде. Вот так выглядит итоговая трассировка стека на IIS7. Вы можете видеть, что первые два фрейма находятся во время выполнения C, также с номерами строк. (На самом деле StackWalker загружает файлы символов с сервера символов MS, если вы используете настройки по умолчанию. Вы можете отключить это, если хотите.)
Тогда следующий набор кадров взят из моего кода. Он точно определяет местонахождение проблемы. Следующие за мной кадры стека - это все модули IIS. Это IIS7 на Vista; Я думаю, что на сервере символов не было символов для этих модулей. В любом случае, как вы можете видеть, трассировка стека не оставляет сомнений в том, где проблема.
f:\dd\vctools\crt_bld\self_x86\crt\src\output.c (1068): _output_l
f:\dd\vctools\crt_bld\self_x86\crt\src\vsprintf.c (405): _vscprintf_helper
f:\dd\vctools\crt_bld\self_x86\crt\src\vsprintf.c (414): _vscprintf
c:\dev\isapi\filter\logger.c (193): LogMessage
c:\dev\isapi\filter\rewriter.c (2036): EvaluateRewrites
c:\dev\isapi\filter\rewriter.c (789): DoRewrites
c:\dev\isapi\filter\rewriter.c (955): OnAuthComplete
c:\dev\isapi\filter\rewriter.c (1139): HttpFilterProc
60531896 module(filter): (filename not available): (function-name not available)
60531FAB module(filter): (filename not available): (function-name not available)
605314E3 module(filter): (filename not available): (function-name not available)
60531276 module(filter): (filename not available): (function-name not available)
6D122EA0 module(iiscore): (filename not available): (function-name not available)
6D123696 module(iiscore): (filename not available): (function-name not available)
6D12AA4C module(iiscore): (filename not available): (function-name not available)
6D125D3B module(iiscore): (filename not available): (function-name not available)
6D1220F4 module(iiscore): (filename not available): (function-name not available)
6D124EEF module(iiscore): (filename not available): (function-name not available)
6D12C6B8 module(iiscore): (filename not available): (function-name not available)
70CB13B3 module(w3dt): (filename not available): UlAtqGetContextProperty
70CB11DA module(w3dt): (filename not available): (function-name not available)
71A42611 module(W3TP): (filename not available): THREAD_POOL::PostCompletion
71A42812 module(W3TP): (filename not available): OverrideThreadPoolConfigWithRegistry
71A41E85 module(W3TP): (filename not available): (function-name not available)
76A54911 module(kernel32): (filename not available): BaseThreadInitThunk
7727E4B6 module(ntdll): (filename not available): __RtlUserThreadStart
7727E489 module(ntdll): (filename not available): _RtlUserThreadStart
7727E489 module(ntdll): (filename not available): _RtlUserThreadStart