Существует несколько возможностей узнать, где было сгенерировано исключение:
Использование макросов компилятора
Использование макросов __FILE__
и __LINE__
в месте выброса (как уже показано другими комментаторами), либо с использованием их в исключениях std в виде текста, либо в качестве отдельных аргументов для пользовательского исключения:
Либо использовать
throw std::runtime_error(msg " at " `__FILE__` ":" `__LINE__`);
или бросок
class my_custom_exception {
my_custom_exception(const char* msg, const char* file, unsigned int line)
...
Обратите внимание, что даже при компиляции для Unicode (в Visual Studio) FILE расширяется до однобайтовой строки.
Это работает в отладке и выпуске. К сожалению, имена исходных файлов с исключениями для бросания кода помещаются в выходной исполняемый файл.
Stack Walking
Выясните местоположение исключения, пройдя стек вызовов.
В Linux с gcc функции backtrace () и backtrace_symbols () могут получать информацию о текущем стеке вызовов. См. gcc документацию , как их использовать. Код должен быть скомпилирован с -g, чтобы символы отладки помещались в исполняемый файл.
В Windows вы можете пройтись по стеку, используя библиотеку dbghelp и ее функцию StackWalk64. См. Статью Йохена Кальмбаха о CodeProject для получения более подробной информации. Это работает в отладке и выпуске, и вам нужно отправить файлы .pdb для всех модулей, о которых вы хотите получить информацию.
Вы даже можете объединить два решения, собирая информацию из стека вызовов при возникновении пользовательского исключения. Стек вызовов может храниться в исключении, как в .NET или Java. Обратите внимание, что сбор стека вызовов в Win32 очень медленный (мой последний тест показал около 6 собранных стеков вызовов в секунду). Если ваш код вызывает много исключений, этот подход значительно замедляет вашу программу.