Я работаю над довольно длинной программой, и, после некоторого времени, нормально работающего, внезапно получаю:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr
Будучи новичком в обработке исключений, я провел небольшое исследование и обнаружил, что, скорее всего, смогу получить больше информации, добавив в свою основную функцию следующее:
int main(int argc, char **argv){
try{
//stuff
}
catch(exception const &exc){
cerr << "Caught exception: " << exc.what() << endl;
}
}
Результатом этого является следующий вывод:
Caught exception: basic_string::substr
Это не более полезно, чем вывод по умолчанию; он ничего не говорит мне о строке, запускающей дамп ядра (в моей программе много вызовов substr), данных, которые substr пытается обработать, и т. д. Есть ли метод для отображения такой информации, как эта, в C++, или мой единственный вариант использовать отладчик, такой как gdb?





Есть несколько способов.
Как вы сказали, отладчик - но это не поможет вам, когда код будет запущен.
Вложенные исключения и блоки попытки функций. например.:
#include <exception>
#include <stdexcept>
#include <iostream>
#include <sstream>
#include <iomanip>
void bar(std::string& s, int i)
try
{
s.at(i) = 'A';
}
catch(...)
{
std::ostringstream ss;
ss << "error in bar(" << std::quoted(s) << ", " << i << ")";
std::throw_with_nested(std::runtime_error(ss.str()));
}
void foo(std::string& s)
try
{
bar(s, 6);
}
catch(...)
{
std::ostringstream ss;
ss << "error in foo(" << std::quoted(s) << ")";
std::throw_with_nested(std::runtime_error(ss.str()));
}
void stuff()
try
{
std::string s;
foo(s);
}
catch(...)
{
std::throw_with_nested(std::runtime_error("error in stuff()"));
}
void print_exception(std::ostream& os, const std::exception& e, int level = 0)
{
os << std::string(level, ' ') << "exception: " << e.what() << '\n';
try {
std::rethrow_if_nested(e);
} catch(const std::exception& e) {
print_exception(os, e, level+1);
} catch(...) {}
}
int main()
{
try{
stuff();
}
catch(std::exception& e)
{
print_exception(std::cerr, e);
return 127;
}
return 0;
}
образец вывода:
exception: error in stuff()
exception: error in foo("")
exception: error in bar("", 6)
exception: basic_string::at: __n (which is 6) >= this->size() (which is 0)
boost::stacktrace вместо вышеупомянутой обработки вложенных исключений.
Что не так с использованием отладчика. Затем он может сказать вам, какая именно строка вызывает исключение ...