记一次程序排错与std::getline
今天忙活了半个下午,查找正式环境上面一个程序的问题。这个程序的作用是监控文件夹,处理每一个文件,分析每个文件的每行记录,然后将这个文件拆分成两个结果文件投放到另外两个不同的目录下面去,当处理完这个文件后,将源文件剪切到备份文件夹下面去。程序的整体逻辑很简单,只用了一天的时间就完成了。可在测试工作完成后,部署到正式环境上面后,今天维护人员突然说有问题,说程序一直在处理一个文件,并且是死循环,处理的结果文件一直在增大,都已经有50多G了。我根据他的描述,说是死循环,一直在处理某个文件。然后我把这个文件取下来单独在测试环境下面测试,一切正常。说明不是文件内容的问题,我想到了文件操作时是不是磁盘坏道的问题,于是乎我一下子就想到代码里的有一个地方可能有问题。这段逻辑大概是这样的:
while(!fs.eof()) // fs的类型是std::fstream
{
std::string str;
std::getline(fs, str);
...
...
}
我就断定代码一定是在这里出问题了,你发现了吗?这个getline竟然没有返回值判断耶,so shit!,当时我这么想的,假如getline出错了,会设定ios::badbit的标记位,这个fstream就不是一个正常的IO了,我也没有做异常处理,接下来程序会一直在这个while循环里做死循环, 因为这个文件不可能会读到文件末尾,也就不会出现读到eof。 接下来我在SO(stack overflow)上面查有没有类似问题,很幸运,竟然有人遇到过类似的问题。我真的只能说 “so sorry that, I am a beginner.”
回到家后,重新打开电脑写了关于getline的程序来验证我的想法,这样做确实会导致死循环的出现(把if判断异常的代码去除)。代码如下:
#include <iostream>
#include <cstdio>
#include <fstream>
#include <string> int main()
{
std::fstream fs;
fs.open("/home/f_x_p/test_code/c++/testfile");
if(!fs.is_open()){
std::cerr << "file open failed!" << std::endl;
return -;
}
int i = ;
while(!fs.eof())
{
std::string str;
if(!std::getline(fs, str)){
std::cerr << "getline failed!" << std::endl;
if((fs.rdstate() & std::fstream::eofbit) != )
{
continue;
}else{
fs.clear();
}
}
std::cout << str << std::endl;
if(i == ){
fs.setstate(std::fstream::badbit);
++i;
}
}
return 0;
}
网上认识的水晶大牛说我应该没那么倒霉,这个地方出错的概率很小。结果如他所说,最终排查的结果不是代码的问题,是维护人员把配置文件搞错了。但我也很自责,配置文件出错,竟然导致了程序的死循环。我只能说 "my code is so shit."
今天真的是血的教训,一个健壮的程序真的是太重要了,以前在代码的健壮性方面确实思考的太少。
记一次程序排错与std::getline的更多相关文章
- 记一次zabbix排错(数据库安装在其它服务器上)
记一次zabbix排错 故障现象 1.在/var/log/zabbix/zabbix_server.log中出现以下报错: 12106:20190314:090947.010 [Z3001] conn ...
- 【转】java线上程序排错经验2 - 线程堆栈分析
前言 在线上的程序中,我们可能经常会碰到程序卡死或者执行很慢的情况,这时候我们希望知道是代码哪里的问题,我们或许迫切希望得到代码运行到哪里了,是哪一步很慢,是否是进入了死循环,或者是否哪一段代码有问题 ...
- 利用c++ std::getline实现split
getline reads characters from an input stream and places them into a string: getline从输入流中读取字符, 并把它们转 ...
- 记32位程序(使用3gb用户虚拟内存)使用D3DX9导致的一个崩溃的问题
为了增加32位程序的用户虚拟内存的使用量,我们使用了/LARGEADDRESSAWARE编译选项来使32位程序可能使用到3gb的内存,能否使用到3gb内存也跟平台.系统和设置有关系,现摘抄部分作为参考 ...
- 小程序排错(redis导致)
小程序突然出问题,题库加载不了,程序正常,测试环境同样环境,同样代码都正常,但是线上数据秒过期,怀疑redis过期时间设置有问题,但是检查配置没问题,写入数据带过期时间也正常. redis设置key: ...
- 记一次samba排错 Failed to start Samba SMB Daemon.
记录一次服务出错排错的过程,很多新手出了点错不百度直接巴拉巴拉的问,一般老手根据经验可以给出一点建议,但是由于个体环境的差异并不适用,反而埋怨起来.这种真的无F**K可说,所以要培养自己的排错能 ...
- 小程序红包开发跳坑记 微信小程序红包接口开发过程中遇到的问题 微信小程序红包开发
现在做小程序的越来越多,商家推广也是一个瓶颈,谁不发点红包,都很难找到人来用你的微信小程序了.于是不管你开发什么小程序功能,你或多或少都要用到小程序来发红包吧. 我们自己之前做公众号发红包,做了两三 ...
- TFboy养成记 简单小程序(Variable & placeholder)
学习参考周莫烦的视频. Variable:主要是用于训练变量之类的.比如我们经常使用的网络权重,偏置. 值得注意的是Variable在声明是必须赋予初始值.在训练过程中该值很可能会进行不断的加减操作变 ...
- 记一次程序从x86_64linux平台移植到armv7平台
前言 最近接了个任务,需要把代码移植到armv7平台,搜寻相关方法,了解到可以利用交叉编译工具如:gcc-linaro-arm-linux-gnueabihf.把自己依赖的第三方库代码和自己代码分别编 ...
随机推荐
- MySQL学习笔记(1/2)
数据库的学习要求:1.为项目设计表:2.使用SQL(Structure Query Language)语句(SQL编程).其他的都可以使用工具完成. SQL: DDL:创建库.创建表 DML:对数据的 ...
- ASM:《X86汇编语言-从实模式到保护模式》越计卷:实模式下对DMA和Sound Blaster声卡的控制
说实话越计卷作者用了16页(我还是删过的),来讲怎么控制声卡,其实真正归纳起来就那么几点. ★PART1:直接存储访问 1. 总线控制设备(bus master) 在硬件技术不发达的早期,处理器是最重 ...
- sql单表中某一字段重复,取最近3条或几条数据
order by a.uid,a.id; sql查询语句,针对需求:一个表中某一字段是有重复的数据,针对该字段相同的值只取最近的3条或要求的几条: --记录铭心!
- VS更改编辑窗背景
打开Visual Studio 工具→扩展和更新→联机 在搜索框里输入“background”后,搜索结果有很多插件可以更改 Visual Studio 的背景,选择其中的一项,可以在右边进行预览 ...
- STM32F407Discovery开发板使用环境搭建
差不多4年前买了STM32F407Discovery这块开发板,也用它作为我的毕业设计的一部分,今晚整理一下东西,觉得这么不错的东西应该再次利用起来,做个智能家居系统的一部分什么的也不错,于是,记录一 ...
- elk平台搭建
很多时候我们需要对日志做一个集中式的处理,但是通常情况下这些日志都分布到n台机器上面,导致一个结果就是效率比较低,而ELK平台可以帮助我们解决这么一件事情: ELK下载:https://www.ela ...
- x64内核内存空间结构
0x00 前言 本文主要是讨论Windows 7 x64下的内核虚拟地址空间的结构,可以利用WiinDBG调试的扩展命令"!CMKD.kvas"来显示x64下的内核虚拟地址空间的整 ...
- 自定义Toast和RatingBar的简单用例
Toast是一个包含用户点击消息.Toast类会帮助你创建和显示这些.Android中的Toast是一种简易的消息提示框. 当视图显示给用户,在应用程序中显示为浮动 向右划动五角星增加 单击按钮显示自 ...
- Django学习笔记之二
一.使用Django自带的后端管理平台 1.后台创建管理员 python manage.py createsuperuser Email address: admin@example.com Pass ...
- sqoop部署
下载安装包 sqoop-1.99.3-bin-hadoop200.tar.gz 解压 tar zxvf sqoop-1.99.3-bin-hadoop200.tar.gz 建立sqoop链接 ln - ...