代码本来在Windows上开发的,功能基本完毕迁移到Linux上,结果一跑,乱象重重。这里只列出两个。
 
一崩溃:
 /mnt/diskc/db/app/bin/mysqld: double free or corruption (out): 0x00007f09cc00c900 ***
======= Backtrace: =========
/lib64/libc.so.6[0x31434760e6]
/lib64/libc.so.6[0x3143478c13]
/lib64/libc.so.6(fclose+0x14d)[0x314346674d]
/mnt/diskc/db/app/bin/mysqld(……内部代码……)[0x781d59] …… /lib64/libpthread.so.0[0x3143c07851]
/lib64/libc.so.6(clone+0x6d)[0x31434e890d]

二挂死:

查询一张表时正常返回结果,然后正常shutdown关闭程序,就挂住了。用pstack可以打出调用栈来。
Thread 2 (Thread 0x7f8a6c074700 (LWP 1506)):
#0 0x00000031434f806e in __lll_lock_wait_private () from /lib64/libc.so.6
#1 0x0000003143466815 in _L_lock_36 () from /lib64/libc.so.6
#2 0x0000003143466652 in fclose@@GLIBC_2.2.5 () from /lib64/libc.so.6
#3 0x00000000007828f6 in …………内部代码………… ()
#5 0x00000000005e9e7d in closefrm(TABLE*, bool) ()
#6 0x0000000000543122 in free_cache_entry(TABLE*) ()
#7 0x000000000054be7c in close_cached_tables(THD*, TABLE_LIST*, bool, unsigned long) ()
#8 0x000000000054c1a4 in table_def_start_shutdown() ()
#9 0x0000000000512f6c in clean_up(bool) ()
#10 0x00000000005131ee in unireg_end() ()
#11 0x0000000000514b82 in kill_server ()
#12 0x0000000000514c3e in kill_server_thread ()
#13 0x0000003143c07851 in start_thread () from /lib64/libpthread.so.0
#14 0x00000031434e890d in clone () from /lib64/libc.so.6
一头乱麻,索性就从最容易重现的第二个挂死现象查起了。
谷歌一搜fclose __lll_lock_wait_private ,神啊,多是说程序clone之后再fclose有过这样的问题,有的还提供了对glibc的patch,确认了一下,我们的glibc库已经很新了。而且我们的程序虽然有多线程,也对一个文件打开过两次,但这两次操作是在一个线程内部的,所以跟网上的信息不太相符。
 
后来自己写了一个测试程序,在一个程序内两次fopen,再依次关闭,也都正常。又改成主线程里开一次,子线程里开一次,再关,仍都正常。
 
最后没办法仔细查代码,发现关于文件打开我们的流程是:
 
OpenFile(FILE* fp)
{
if (fp != NULL)
fclose(fp); fopen(fp,,,,,);
}

而在某些处理后需要关闭时,操作为:

fclose(fp);
虽然不太确定,但做事总要干净些,于是把关闭操作改为:
fclose(fp);
fp = NULL;
搞完了,一切正常了。说明我们有良好的编码习惯是多么重要。另外出Bug时还是要多查自己的代码,基础库的问题没那么容易被我们撞上的。
 
查查man fclose,说了两次关闭的结果然是不确定的。
RETURN VALUE
Upon successful completion 0 is returned. Otherwise, EOF is returned and errno is
set to indicate the error. In either case any further access (including
another call to fclose()) to the stream results in undefined behavior.
再附上我自己的测试多次fopen的代码。
#include <stdio.h>
#include <pthread.h> char szPath[312] = {0};
char readbuf[312] = {0}; void* thread_func(void* p)
{
printf("\n\n....hello from son thread %d\n", pthread_self());
FILE *fp_r = NULL;
fp_r = fopen(szPath, "rb+");
printf("fp_r=%d after fopen rb+ \n", fp_r); if (fp_r == NULL)
return NULL; if (fread(readbuf, 10, 1, fp_r) < 0 )
{
printf("read fp_r error!!\n");
return NULL;
}
printf("read fp_r ok!!\n");
sleep(10); fclose(fp_r);
printf("close fp_r ok!!\n"); pthread_exit(NULL);
} int main()
{
FILE *fp_w = NULL; pthread_t t_id ; sprintf(szPath, "/disk1/tmp"); fp_w = fopen(szPath, "wb+");
printf("fp_w=%d after fopen wb+ \n", fp_w); if (fp_w == NULL)
{
return 0;
} if (fwrite(szPath, sizeof(szPath), 1, fp_w) != 1)
{
return -1;
} fclose(fp_w);
printf("fp_w=%d after fclose wb+ \n", fp_w);
fp_w = NULL; fp_w = fopen(szPath, "rb+");
printf("fp_w=%d after fopen rb+ \n", fp_w); if (fp_w == NULL)
return -1; if (fread(readbuf, 10, 1, fp_w) < 0)
{
printf("read fp_w error!!\n");
return -1;
}
printf("read fp_w ok!!\n"); if (pthread_create(&t_id, NULL, &thread_func, (void*)&t_id) != 0)
{
printf(" pthread_create fail!! \n");
return -1;
}
printf("create thread done.\n");
sleep(3); fclose(fp_w);
printf("close fp_w ok!!\n");
pthread_join(t_id,NULL);
printf("-----------------------\n"); return 0;
}

编译命令为:gcc tfclose.c -lpthread

两次fclose引发的血案的更多相关文章

  1. dubbox微服务实例及引发的“血案”

    Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成. 主要核心部件: Remoting: 网络通信框架 ...

  2. Replication的犄角旮旯(七)-- 一个DDL引发的血案(下)(聊聊logreader的延迟)

    <Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...

  3. 转:一个Sqrt函数引发的血案

    转自:http://www.cnblogs.com/pkuoliver/archive/2010/10/06/1844725.html 源码下载地址:http://diducoder.com/sotr ...

  4. 一个Sqrt函数引发的血案(转)

    作者: 码农1946  来源: 博客园  发布时间: 2013-10-09 11:37  阅读: 4556 次  推荐: 41   原文链接   [收藏]   好吧,我承认我标题党了,不过既然你来了, ...

  5. 一个字母引发的血案 java.io.File中mkdir()和mkdirs()

    一个字母引发的血案 明天开始放年假了,临放假前有个爬虫的任务,其中需要把网络图片保存到本地,很简单,马上写完了代码: //省略部分代码... Long fileId= (Long) data.get( ...

  6. form表单提交引发的血案

    最近,公司某条产品线上的一个功能出了问题:点击查询的时候,该页面在IE上直接卡死,chrome上会卡顿一段时间候提交表单进行查询.拿到这个bug单子以后,简单重现了下,基本上定位到是查询操作中的问题, ...

  7. elasticsearch5.0.1集群一次误删除kibana索引引发的血案

    elasticsearch集群中一次删除kibana索引引发的血案 1.问题发生的过程: 早上的时候有某个索引无法看到报表数据,于是就点该报表多次,估计集群被点挂了,报错:Elasticsearch ...

  8. 一个无锁消息队列引发的血案(六)——RingQueue(中) 休眠的艺术 [续]

    目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...

  9. 一个无锁消息队列引发的血案(五)——RingQueue(中) 休眠的艺术

    目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...

随机推荐

  1. U10vim程序编辑器

    vim需要多加练习. 1.你可以将vim视为vi的高级版本.vi分成三种模式:一般模式,编辑模式和命令行模式. 一般模式:以vi打开一个文件就直接进入一般模式了(这也是默认的模式).在这个模式中,你可 ...

  2. Mina框架断包、粘包问题解决方式

    Mina框架断包.粘包问题解决方式 Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP.UDP/IP协议栈的通信框架(当然.也能够提供JAVA 对象的序 ...

  3. hunnu-11546--Sum of f(x)

    Sum of f(x) Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB Total submit users:  ...

  4. quick-cocos2d-x游戏开发【4】——加入文本

    文本的加入在quick中被封装在ui类中,它能够创建EditBox.菜单以及文本,文本总得来说能够创建TTF和BMFont两种. api对于它的说明非常具体.ui.newBMFontLabel(par ...

  5. HDU 1661 Assigments 贪心法题解

    Problem Description In a factory, there are N workers to finish two types of tasks (A and B). Each t ...

  6. 黄聪:Microsoft Enterprise Library 5.0 系列教程(十) Configuration Application Block

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(十) Configuration Application Block 到目前为止,我们使用的模块都是在同一个配置 ...

  7. Kinect的学习笔记发展(一)Kinect引进和应用

    Kinect的学习笔记发展(一)Kinect引进和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...

  8. LAMBDA表达式常用 (全)

    这里主要是将数据库中的常用操作用LAMBDA表达式重新表示了下,用法不多,但相对较常用,等有时间了还会扩展,并将查询语句及LINQ到时也一并重新整理下: 1.select语句:books.Select ...

  9. SQL Server :理解DCM页

    原文:SQL Server :理解DCM页 我们已经讨论了各种不同的页,包括数据页.GAM与SGAM页.PFS页,还有IAM页.今天我们来看下差异变更页(Differential Change Map ...

  10. NDK/JNI学习--进口hello-jniproject

    上一篇文章,简单的设置NDK开发环境,本文通过导入C:\android-ndk-r9d\samples\hello-jni(NDK自带example)来疏通真个环境. 打开Eclipse IDE.指定 ...