转载自http://www.cnblogs.com/mumuxinfei/p/4363466.html

前言:    
  最近有个项目, 需要访问第三方服务. 该服务是通过http的形式访问的, 为了安全和加密, 对方提供了一个加密用的C/C++库, 用于对参数进行处理.  鉴于此, 选用了C/C++语言, 以libcurl作为http类库来编写该服务模块. 这为后续的坑埋下了伏笔.
  

状况简述:
  程序采用Reactor模型, IO线程专做IO事件读写, 以及请求的dispatch分发, 后端线程池用于业务的同步操作. 对libcurl的使用, 也穿插在多线程中. 
  当程序功能完成后, 对其进行压力测试. 过了大致20分钟, 程序crash并出core.

  

  gdb调core后, 发现其在epoll_wait之上的调用栈出问题了.
  根据经验, 本着谁肇事, 谁擦屁股的原则, 对该线程以及epoll调用方做了艰苦卓绝, 却步履维艰的排查. 后面的事实证明, 这是条不归路, duang duang duang.....

逆向推测:
  起初的排查没有效果, 于是乎, 采用逆向思维. 从SIGABRT 6信号出发, 看看什么情况下能触发该信号.
  指针的重复删除会引发该错误, 如下面例子:
  
  其他的内存操作, 如野指针的使用, 越界, 往往对应的是SIGSEGV 11. 
  于是乎, 寻找疑似double delete的情况, 结果还是一无所获.

信号认识:
  真相只有一个, 可惜在那里呢? 是那个环节出错呢?
  无意中, 再次扫了下堆栈, 徒然发现 <signal handler called>
  
  看来epoll_wait的线程, 是被信号中断, 并执行了该信号回调函数(其来源标明了libcurl.so.4), 并在该信号处理函数中出SIGABRT 6.
  让我们回忆下, 信号的处理.
  raise函数, 会把信号发送给本线程. 而其他函数(如kill, alarm), 向进程发送信号, 但具体执行该信号处理函数的线程是不确定的.
  现在离真相已经很接近了: 某线程触发信号, epoll_wait线程则执行了该信号处理函数, 可惜在这个处理函数中, 出了异常. 和epoll_wait无关, 与其调用方也没关系.
  那某函数(黑衣人)是谁呢? 和libcurl有关系不?

拨开云雾:
  通过搜索引擎, 发现"libcurl 多线程使用注意事项", "Libcurl多线程crash问题" 这两篇文章. 
  真相终于浮现出来了, 原来libcurl的超时机制默认是通过信号sigalrm, setjmp/longjmp函数来实现的, 在多线程情况下, 会导致程序crash. 
  这官方的说明, 也解释了core栈上的异常信息.
  最终的解决方案就是, CURLOPT_NOSIGNAL设置为1.

1
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);

总结:
  甲方虐我千百遍, 我待甲方如初恋. 虽然被libcurl坑, 但对信号的理解更深刻了, 终是好事. 但C/C++和Java实现同样的业务功能时, C/C++ Coder需要了解更多的细节, 抬高门槛的同时, 也增加开发难度和开发时间, 未免有点得不偿失. 这篇文章不是语言之争, 就此打住.

【转载】linux信号处理及libcurl的坑的更多相关文章

  1. linux信号处理及libcurl的坑

    前言:     最近有个项目, 需要访问第三方服务. 该服务是通过http的形式访问的, 为了安全和加密, 对方提供了一个加密用的C/C++库, 用于对参数进行处理.  鉴于此, 选用了C/C++语言 ...

  2. [转载]Linux进程调度原理

    [转载]Linux进程调度原理 Linux进程调度原理 Linux进程调度的目标 1.高效性:高效意味着在相同的时间下要完成更多的任务.调度程序会被频繁的执行,所以调度程序要尽可能的高效: 2.加强交 ...

  3. linux 信号处理 五 (示例)

    [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执 ...

  4. linux信号处理相关知识

      因为要处理最近项目中碰上的多个子进程退出信号同时到达,导致程序不当产生core的情况,今天我花了时间看了一些关于linux信号处理的博客. 总结一下:(知识未经实践) linux信号分两种,一种实 ...

  5. [转载]Linux下非root用户如何安装软件

    [转载]Linux下非root用户如何安装软件 来源:https://tlanyan.me/work-with-linux-without-root-permission/ 这是本人遇到的实际问题,之 ...

  6. [转载]Linux 命令详解:./configure、make、make install 命令

    [转载]Linux 命令详解:./configure.make.make install 命令 来源:https://www.cnblogs.com/tinywan/p/7230039.html 这些 ...

  7. [转载]Linux缓存机制

    [转载]Linux缓存机制 来源:https://blog.csdn.net/weixin_38278334/article/details/96478405 linux下的缓存机制及清理buffer ...

  8. [转载] Linux五种IO模型

      转载:http://blog.csdn.net/jay900323/article/details/18141217     Linux五种IO模型性能分析   目录(?)[-] 概念理解 Lin ...

  9. [转载]Linux内核编译

    原文地址:https://blog.csdn.net/qq_34247099/article/details/50949720 写在前面的话: 本人大二,东南大学一个软工狗,正在修一门名为<操作 ...

随机推荐

  1. hdu 4192

    dfs全排列  加  模拟计算 #include <iostream> #include <cstdio> #include <cstdlib> #include ...

  2. java CMS gc解析

    转载: http://www.blogjava.net/killme2008/archive/2009/09/22/295931.html     CMS,全称Concurrent Low Pause ...

  3. [topcoder]AvoidRoads

    二维动态规划.和某一道leetcode的题目差不多.就是多了blocks的数组或集合. 本次解题的心得有:1.根据题意使用集合表示阻碍:2.使用字符串的形式表示整数的pair,简洁明了:3.p1到p2 ...

  4. pflua:用Lua编写的高性能网络包过滤工具箱

    http://www.csdn.net/article/2014-09-05/2821568-pflua

  5. (转)CSS+DIV float 定位

    来自:http://www.cnblogs.com/iyangyuan/archive/2013/03/27/2983813.html 很早以前就接触过CSS,但对于浮动始终非常迷惑,可能是自身理解能 ...

  6. MySQL数据库服务器安装标准

    MySQL数据库服务器安装标准 (1).BIOS优化,阵列配置 1.1:关闭CPU节能,因为服务器品牌众多,BIOS设置不相同,主要是关闭CPU节能,如C1,DELLR730,已经智能设置,直接有个p ...

  7. 新版本的tlplayer for android ,TigerLeapMC for windows发布了

    tlplayer for android 新版本修正了图像倾斜等等问题,增加了动态水印功能. 支持hls(m3u8),http,rtsp,mms,rtmp等网络协议. 声明tlplayer 上的变速不 ...

  8. 转载:C++ map的基本操作和使用

    声明:本文转自:http://www.cnblogs.com/hailexuexi/archive/2012/04/10/2440209.html 1.map简介 map是一类关联式容器.它的特点是增 ...

  9. Java面试题-并发工具

    1. 如何实现一个流控程序,用于控制请求的调用次数?

  10. java 参数传递是引用传递还是值传递?

    JAVA的参数传递倒底是值传递还是引用传递,我觉得两种说法都没错,关键是看怎么理解“引用”和“引用传递”. (一)从编译原理的角度讲,所有那些无法通过形参来修改实参本身的传递机制都是“值传递”,在JA ...