公司的机器最近遇到一个bug(其实这个bug一年前就出现过,只是未引起重视),现象是这样的:在生产环境中,用户连续打印票的时候,中间某张票的一个时间可能会出问题,该时间本来是一个未来的时间,却被打印成了系统当前的时间.其他同事认为是传入的参数出错了,加了大量的调试信息和日志进去,结果去令人掉眼镜,传入的参数是完全正确的,但是结果去不是预期的.

  最终排查BUG的任务转到了我手里,我简单分析了下上层流程,并无问题,于是把问题定位在底层库的FormatTime函数上,于是要了份FormatTime的代码查看(吐槽下,封闭的代码库往往造就一些隐蔽的问题),FormatTime的实现很简单,调用localtime函数,然后格式化输出,查看localtime函数的原型,如下

 struct tm *localtime(const time_t *timep);

  问题就出在localtime这个函数上,从函数原型来看,这个函数返回了一个struct tm的指针,但是传入参数并未有传入tm参数,那么就有3种情况

1,tm是内部malloc出来的

2,tm是一个全局变量

3,tm是一个局部static

  第一种情可以首先排除,因为调用完localtime后没要求free tm,或者提供相应的free函数,第2 3种情况可以视为一种情况,那即是:使用了内部全局变量!

  那么问题就来了,这个函数是个非线程安全的函数,在多线程的环境下使用,会发生重入的情况,即如果两个线程同时调用localtime函数,函数的返回结果都会是最后一次调用localtime的结果.这是一个典型的函数重入BUG.解决方法:使用线程安全的localtime_r函数替换localtime.至此,问题解决

  c语言中有不少函数都是非线程安全的,例如strtok,gethostbyname,看到返回值为指针类型的函数时,都要留个心眼.

转载于:https://www.cnblogs.com/Red_angelX/archive/2013/05/24/3097098.html

c语言非线程安全函数引发的BUG一列相关推荐

  1. 网络编程(36)—— 线程安全函数和非线程安全函数

    今天研究下线程安全函数和非线程安全函数.什么是线程安全函数?我们知道在多线程编程中,线程安全问题是不容忽视的.只要存在多线程,就会存在多个线程访问同一段代码或者同一个全局变量的临界区,对于uc中标准函 ...

  2. c语言调度线程的函数是哪个,C语言线程函数

    除了创建线程的 thread_create()函数.获取返回值的 thread_join()函数和释放线程占用资源的 thread_detach()函数,C11 还提供了另外用于线程控制的 5 个函数 ...

  3. C语言一定要有函数声明吗,1 什么是C语言的隐式函数声明在C语言中,函数在调用前不一定非要声明。如果没有声明,那么编译器会自动按照一种隐式声明的规则,为调用函数的C代码产生汇编代码。下...

    1 什么是C语言的隐式函数声明 在C语言中,函数在调用前不一定非要声明.如果没有声明,那么编译器会自动按照一种隐式声明的规则,为调用函数的C代码产生汇编代码.下面是一个例子: int main(int ...

  4. 【Android NDK 开发】JNI 线程 ( JNI 线程创建 | 线程执行函数 | 非 JNI 方法获取 JNIEnv 与 Java 对象 | 线程获取 JNIEnv | 全局变量设置 )

    文章目录 I . JNI 线程创建 II . 线程执行函数 III . 线程方法获取 Java 对象 IV . 线程方法获取 JNIEnv V . JNI 线程 完整代码示例 I . JNI 线程创建 ...

  5. 【C++ 语言】线程 ( 线程创建方法 | 线程标识符 | 线程属性 | 线程属性初始化 | 线程属性销毁 | 分离线程 | 线程调度策略 | 线程优先级 | 线程等待 )

    文章目录 I 线程创建方法 II 线程执行函数 III 线程标识符 IV 线程属性 V 线程属性 1 ( 分离线程 | 非分离线程 ) VI 线程属性 2 ( 线程调度策略 ) VII 线程属性 3 ...

  6. mysql 线程池源码模块_易语言Mysql线程池2.0模块源码

    易语言Mysql线程池2.0模块源码 易语言Mysql线程池2.0模块源码 系统结构:GetThis,初始化,关闭类线程,线程_测试,其他_附加文本,连接池初始化,取mysql句柄,释放mysql句柄 ...

  7. Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口(四)

    前言: 在前面的系列中,我们虽然完成了其大部分功能,但是,离正真运行,还是有一大段距离 当你F5运行时,在弹出对话框之后,如果你不即时点确定,或者上个WC回来之后,你会发现已经提示出错了 这节开始,我 ...

  8. 使用C#调用非托管DLL函数

    由于工作需要,学习了GDI+编程的一些知识.其中看到了一个比较好的Demo,深入的了解后,却发现自己对如何用C#调用非托管DLL函数也有了更好的理解,于是整理了一下,跟大家一起分享. 引用: 用C#来 ...

  9. win32 c语言创建线程,【原创】win32线程及线程内核对象

    内核对象与GDI对象 GDI对象: 1. DC 2. 画笔 3. 画刷 内核对象 1. 进程 process 2. 线程 thread 3. 文件 file 4. 事件 envent 5. 信号量 s ...

最新文章

  1. s5-6 Linux 标准输出 系统优化 目录结构
  2. python查看文件的编码格式
  3. linux升级补丁tar,Linux下Bash严重漏洞补丁升级方法
  4. Spring Security 入门(1-9)国际化的使用
  5. 软件工程---3.敏捷软件开发
  6. asp控制oracle,asp下用OracleInProcServer完成对Oracle的连接和操作
  7. Adobe illustrator 设置字体和微调 - 连载 10
  8. 高德地图JS-API (超简单Get新技能√)
  9. 大学计算机vb基础知识6,计算机基础课-VB6选择题汇编(2011-2016)
  10. steam++(GitHub加速)433端口占用解决方案
  11. 关于Y400 电源管理 Win10解决方案
  12. 阿里巴巴移动技术 2021 年终盘点
  13. oracle erp atp是什么意思,三种ATP(ERP原理与应用教程第2版)
  14. 2021节假日安排,免费拿走
  15. 关于解决无线拨号(PPPOE)上网的若干问题(WISP)
  16. linux跨平台通信软件,下载:跨平台即时通信工具Pidgin 2.7.5
  17. 路由器的CPU和存储器
  18. 华为G9怎么找到云相册_华为G9 Plus图赏:全方位均衡的中端机
  19. Excel 2010 VBA 入门 031 批量生成上标
  20. 5G 频段 频率与Band对应表

热门文章

  1. coffeescript html5,HTML5——前端预处理技术(Less、Sass、CoffeeScript)
  2. STM32-时钟-时钟树-时钟初始化配置
  3. 存储器和寄存器数据传输(ARMv8)
  4. oracle 修改2个表,oracle学习笔记2:创建修改表
  5. Java Springboot+VUE前后端分离网上手机商城平台系统设计和实现以及论文报告
  6. android 菜单 功能键,Android交互体验必知:功能按键事件
  7. python数据分析函数大全_python中数据分析常用函数整理
  8. java项目如何单元测试_大家java web项目开发做单元测试吗?
  9. 修改SqlServer的登录密码
  10. 【youcans 的 OpenCV 例程 200 篇】102. 陷波带阻滤波器的传递函数