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用于捕获并处理异常,然后程序可以继续执行正常的代码路径。这是异常处理的核心概念,允许程序在遇到错误时进行优雅的错误处理而不致于崩溃。

 

posted @ 2024-01-01 14:01  He_LiangLiang  阅读(104)  评论(0编辑  收藏  举报