C++抛出的异常,要学会排查
记录一次异常的排查
// 这是yam-cpp源代码里面,YAML::LoadFile的方法 Node LoadFile(const std::string& filename) { std::ifstream fin(filename); if (!fin) { throw BadFile(filename); } return Load(fin); }
执行这行加载文件代码的时候,异常了:
YAML::Node root = YAML::LoadFile("/home/henry/workspace/henry-sylar/bin/conf/log2.yml");
异常信息如下:
[henry@192 bin]$ ./test_thread 2024-01-01 13:52:48 5670 0 [INFO] [root] tests/test_thread.cpp:37 thread test begin terminate called after throwing an instance of 'YAML::BadFile' what(): bad file: /home/henry/workspace/henry-sylar/bin/conf/log2.yml Aborted
首先,第一反应是 这里是抛出了异常。
其次,结合代码逻辑,我们定位到异常是 YAML::LoadFile() 这个方法执行之后抛出的。
然后我们去看这个LoadFile方法的实现细节。
最后我们定位到了 throw BadFile(filename) 这行。发现是日志路径有问题,LoadFile函数没有找到这个文件,然后抛出了异常。
为了加深对 抛出异常的理解,这里专门写了一个抛出异常的程序。
// ex.cpp #include <iostream> void test_ex() { throw std::logic_error("this is a exception test"); } int main() { test_ex(); return 0; } // g++ ex.cpp --std=c++11 -o ex.bin
## 编译 ex.cpp 文件 [henry@192 build]$ g++ ex.cpp --std=c++11 -o ex.bin ##执行ex.cpp文件 [henry@192 build]$ ./ex.bin ## 异常信息如下: terminate called after throwing an instance of 'std::logic_error' what(): this is a exception test Aborted
throw 抛出异常,如果没有匹配的catch
块,
程序会终止并调用std::terminate
,这会导致程序异常终止。
-
throw语句:
- 当
throw
语句执行时,程序会立即跳转到最近的匹配的catch
块,中断当前的正常执行流程。 - 如果没有匹配的
catch
块,程序会终止并调用std::terminate
,这会导致程序异常终止。
- 当
-
catch语句:
- 当某个
throw
语句抛出异常时,会检查try
块中是否有匹配的catch
块。 - 如果有匹配的
catch
块,程序会进入该catch
块执行相关的处理代码,然后继续执行程序的正常流程。 - 如果没有匹配的
catch
块,异常会沿着调用堆栈向上传递,寻找包含匹配catch
块的最近的外围try
块。
- 当某个
总体而言,throw
中断了当前的执行流程,并跳转到异常处理代码;而catch
用于捕获并处理异常,然后程序可以继续执行正常的代码路径。这是异常处理的核心概念,允许程序在遇到错误时进行优雅的错误处理而不致于崩溃。