今天忙活了半个下午,查找正式环境上面一个程序的问题。这个程序的作用是监控文件夹,处理每一个文件,分析每个文件的每行记录,然后将这个文件拆分成两个结果文件投放到另外两个不同的目录下面去,当处理完这个文件后,将源文件剪切到备份文件夹下面去。程序的整体逻辑很简单,只用了一天的时间就完成了。可在测试工作完成后,部署到正式环境上面后,今天维护人员突然说有问题,说程序一直在处理一个文件,并且是死循环,处理的结果文件一直在增大,都已经有50多G了。我根据他的描述,说是死循环,一直在处理某个文件。然后我把这个文件取下来单独在测试环境下面测试,一切正常。说明不是文件内容的问题,我想到了文件操作时是不是磁盘坏道的问题,于是乎我一下子就想到代码里的有一个地方可能有问题。这段逻辑大概是这样的:

  1. while(!fs.eof()) // fs的类型是std::fstream
  2. {
  3. std::string str;
  4. std::getline(fs, str);
  5. ...
  6. ...
  7. }

我就断定代码一定是在这里出问题了,你发现了吗?这个getline竟然没有返回值判断耶,so shit!,当时我这么想的,假如getline出错了,会设定ios::badbit的标记位,这个fstream就不是一个正常的IO了,我也没有做异常处理,接下来程序会一直在这个while循环里做死循环, 因为这个文件不可能会读到文件末尾,也就不会出现读到eof。 接下来我在SO(stack overflow)上面查有没有类似问题,很幸运,竟然有人遇到过类似的问题。我真的只能说 “so sorry that, I am a beginner.”

回到家后,重新打开电脑写了关于getline的程序来验证我的想法,这样做确实会导致死循环的出现(把if判断异常的代码去除)。代码如下:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <fstream>
  4. #include <string>
  5.  
  6. int main()
  7. {
  8. std::fstream fs;
  9. fs.open("/home/f_x_p/test_code/c++/testfile");
  10. if(!fs.is_open()){
  11. std::cerr << "file open failed!" << std::endl;
  12. return -;
  13. }
  14. int i = ;
  15. while(!fs.eof())
  16. {
  17. std::string str;
  18. if(!std::getline(fs, str)){
  19. std::cerr << "getline failed!" << std::endl;
  20. if((fs.rdstate() & std::fstream::eofbit) != )
  21. {
  22. continue;
  23. }else{
  24. fs.clear();
  25. }
  26. }
  27. std::cout << str << std::endl;
  28. if(i == ){
  29. fs.setstate(std::fstream::badbit);
  30. ++i;
  31. }
  32. }

  33.   return 0;
  34. }

网上认识的水晶大牛说我应该没那么倒霉,这个地方出错的概率很小。结果如他所说,最终排查的结果不是代码的问题,是维护人员把配置文件搞错了。但我也很自责,配置文件出错,竟然导致了程序的死循环。我只能说 "my code is so shit."

今天真的是血的教训,一个健壮的程序真的是太重要了,以前在代码的健壮性方面确实思考的太少。

记一次程序排错与std::getline的更多相关文章

  1. 记一次zabbix排错(数据库安装在其它服务器上)

    记一次zabbix排错 故障现象 1.在/var/log/zabbix/zabbix_server.log中出现以下报错: 12106:20190314:090947.010 [Z3001] conn ...

  2. 【转】java线上程序排错经验2 - 线程堆栈分析

    前言 在线上的程序中,我们可能经常会碰到程序卡死或者执行很慢的情况,这时候我们希望知道是代码哪里的问题,我们或许迫切希望得到代码运行到哪里了,是哪一步很慢,是否是进入了死循环,或者是否哪一段代码有问题 ...

  3. 利用c++ std::getline实现split

    getline reads characters from an input stream and places them into a string: getline从输入流中读取字符, 并把它们转 ...

  4. 记32位程序(使用3gb用户虚拟内存)使用D3DX9导致的一个崩溃的问题

    为了增加32位程序的用户虚拟内存的使用量,我们使用了/LARGEADDRESSAWARE编译选项来使32位程序可能使用到3gb的内存,能否使用到3gb内存也跟平台.系统和设置有关系,现摘抄部分作为参考 ...

  5. 小程序排错(redis导致)

    小程序突然出问题,题库加载不了,程序正常,测试环境同样环境,同样代码都正常,但是线上数据秒过期,怀疑redis过期时间设置有问题,但是检查配置没问题,写入数据带过期时间也正常. redis设置key: ...

  6. 记一次samba排错 Failed to start Samba SMB Daemon.

       记录一次服务出错排错的过程,很多新手出了点错不百度直接巴拉巴拉的问,一般老手根据经验可以给出一点建议,但是由于个体环境的差异并不适用,反而埋怨起来.这种真的无F**K可说,所以要培养自己的排错能 ...

  7. 小程序红包开发跳坑记 微信小程序红包接口开发过程中遇到的问题 微信小程序红包开发

    现在做小程序的越来越多,商家推广也是一个瓶颈,谁不发点红包,都很难找到人来用你的微信小程序了.于是不管你开发什么小程序功能,你或多或少都要用到小程序来发红包吧.  我们自己之前做公众号发红包,做了两三 ...

  8. TFboy养成记 简单小程序(Variable & placeholder)

    学习参考周莫烦的视频. Variable:主要是用于训练变量之类的.比如我们经常使用的网络权重,偏置. 值得注意的是Variable在声明是必须赋予初始值.在训练过程中该值很可能会进行不断的加减操作变 ...

  9. 记一次程序从x86_64linux平台移植到armv7平台

    前言 最近接了个任务,需要把代码移植到armv7平台,搜寻相关方法,了解到可以利用交叉编译工具如:gcc-linaro-arm-linux-gnueabihf.把自己依赖的第三方库代码和自己代码分别编 ...

随机推荐

  1. FreeImage编译及遇到问题解决

    FreeImage编译及遇到问题解决 1.下载freeImage源码包 wget http://downloads.sourceforge.net/freeimage/FreeImage3170.zi ...

  2. Qt应用程序图标设置

    Qt应用程序图标设置 本文仅仅适用于windows下,linux等不适用. 下面说的图标,指的是程序文件的图标,而不是托盘图标或者说运行时任务栏的图标(任务栏和程序窗口的图标在windows/linu ...

  3. p2p音视频通信

    今年音频没事干了,根据业务需求,调研音视频p2p通信,减小服务器压力,一切从0开始. 需要信令服务器,打洞服务器,帮助链接打通双方,实现p2p音视频通信. 服务器和客服端交互等都需要实现. 谷歌web ...

  4. ASM:《X86汇编语言-从实模式到保护模式》第9章:实模式下中断机制和实时时钟

    中断是处理器一个非常重要的工作机制.第9章是讲中断在实模式下如何工作,第17章是讲中断在保护模式下如何工作. ★PART1:外部硬件中断 外部硬件中断是通过两个信号线引入处理器内部的,这两条线分别叫N ...

  5. 【XLL 框架库函数】 TempActiveColumn/TempActiveColumn12

    创建一个包含所有激活工作表列的 XLOPER/XLOPER12 LPXLOPER TempActiveColumn(BYTE col); LPXLOPER12 TempActiveColumn12(C ...

  6. LINK1123:failure during conversion to COFF:file invalid or corrupt

    参考 http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=20726500&id=4528320 试了微软官方说明:http ...

  7. Oracle的优化器介绍

    Oracle优化器介绍 本文讲述了Oracle优化器的概念.工作原理和使用方法,兼顾了Oracle8i.9i以及最新的10g三个版本.理解本文将有助于您更好的更有效的进行SQL优化工作. RBO优化器 ...

  8. 反调试技术常用API,用来对付检测od和自动退出程序

    在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...

  9. react native中对props和state的理解

    最近使用react native这个新的技术做完一个项目,所以赶紧写个博客巩固一下. 今天我想说的是props和state,当然这是我个人的理解,如果有什么不对的地方,望指正. 首先我先说说props ...

  10. ASP.NET常见面试题及答案(130题)

    1.C#中 property 与 attribute(抽像类)的区别,他们各有什么用处,这种机制的好处在哪里?答:property和attribute汉语都称之为属性.不过property是指类向外提 ...