shell如何判定C/C++程序是否执行成功

linux编程中经常遇到这样的问题,即判断一个程序执行是否成功, 通常实现方法是通过进程的退出状态来判断,当linux的一个进程执行完成后会返回一个进程的退出状态,通过判断退出状态码可以确定该程序是否执行成功,shell中$? 表示上个命令的退出状态,最简单的获取退出状态的shell测试脚本实现如下:

./shellTest1
echo "return val is "$?

其中shellTest1为待判断程序,我们给一个最简单的C++程序,shellTest1.cpp的代码如下:

#include<iostream>
using namespace std;
int main()
{

return 0;
}

执行测试脚本,此时输出为:

return val is 0

即如果程序main函数有返回值,返回的状态码就是返回值,但需要注意,状态码取值范围为0-255,所以如果实际返回值多于8位依然返回低8位(这里指2进制),例如shellTest1.cpp中返回值改为return -1,则输出为:

return val is 255

若改为return 512,则输出为:

return val is 0

若改为return 515,则输出为:

return val is 3

当然除了程序执行main函数直接返回外,还会存在程序异常导致进程提前终止的情况,linux退出状态有如下几种:

0  命令成功结束
1  一般性未知错误
2  不适合的shell命令
126 命令不可执行
127 没找到命令
128 无效的退出参数
128+x 与Linux信号x相关的严重错误
130 通过Ctrl+C终止的命令
255 正常范围之外的退出状态码

例如我们将shell测试脚本改为:

./shellTest2
echo "return val is "$?

而当前目录shellTest2可执行程序不存在,执行脚本输出结果为:

return val is 127

即没有找到命令。

我们再考虑两个常用的错误,第一个是空指针的问题,修改shellTest1.cpp的代码为:

#include<iostream>
using namespace std;
int main()
{
float *p;
*p=12;
cout<<*p<<endl;
return 0;
}

此时测试脚本的输出为

return val is 139

显然根据linux退出状态,其返回的是linux信号相关的严重错误,对应终止信号为11,关于终止信号可以参考终止信号状态码,可以查到其对应的信号名称为SIGSEGVSIGSEGV是当一个进程执行了一个无效的内存引用,或发生段错误时发送给它的信号,显然这里是执行了一个无效的内存引用。再看一个常见问题,即内存不足的问题,修改shellTest1.cpp的代码为:

#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<float> tmpData;
tmpData.resize(11000000000);
return 0;
}

这里申请了一块超大内存,导致物理内存不够,因此会导致程序异常退出,测试脚本输出为:

return val is 134

终止信号为6,同样,我们可以查到对应信号名称为SIGABRTSIGABRT常见错误为1)double free/free 没有初始化的地址或者错误的地址2)堆越界 3)assert,显然这里是内存不足导致的堆越界。

最后总结下:

1.最好设定程序执行正确返回值为0(返回状态码为0),不正确返回值为-1(返回状态码为255),这样不管发生什么异常只要退出状态码不为0,那么程序就没有执行成功;以测试代码为例,可写为

./shellTest1
if [ $? -ne 0 ];then
    exit 1
else
    exit 0
fi

2.在第一步基础上,可以进一步根据返回状态码记录错误出在哪里(内存泄漏、野指针等),便于快速定位程序问题在哪里。

3.对于函数多个返回值的情况,例如函数执行到不同的位置遇到不同的错误,可通过不同返回值来确认,这里我们可以选择3-125这些数字作为返回值来确认错误。

4.shell脚本和C++程序操作类似,区别就是shell脚本通过exit设定脚本返回值。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值