libuuid.so 崩溃问题
来源:互联网 发布:linux dhcp安装包 编辑:程序博客网 时间:2024/05/18 10:54
前段时间使用的Cetos 6.3有程序崩溃在了uuid_generate () from /lib64/libuuid.so.1,现象很是诡异,libuuid是Centos util-linux工具包中自带的一个系统库,怎么可能在这里出问题。首先怀疑是上层应用不正确的使用libuuid库导致的问题,对应用代码进行review和debug也没有发现问题。最为奇怪的是,这个问题在使用官方ISO镜像安装的Centos 6.5上也会出现,但是在我们一直使用的另外的基于Centos 6.5系统做的系统镜像上不会有问题。排查许久,终于找到了根本原因,这里记录一下。
1 首先重新编译libuuid添加调试信息
下载到的util-linux-ng-2.17.2-12.24.el6.src.rpm安装后会在rpmbuild/SPECS下生成一个util-linux-ng.spec文件,里面有一行:
export CFLAGS="-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 $RPM_OPT_FLAGS"
RPM_OPT_FLAGS 是控制编译选项,编译器-g3选项就要在这里加入。man rpmbuild查看手册,得到下面的信息:
is present in each file, the value of the entry read last is the one used by RPM.
This means, for example, that an entry in .rpmrc in the user's login directory will
always override the same entry in /etc/rpmrc. Likewise, an entry in /etc/rpmrc
will always override the same entry in /usr/lib/rpmrc.
#ifdef HAVE_TLS#define THREAD_LOCAL static __thread#else#define THREAD_LOCAL static#endif#if defined(__linux__) && defined(__NR_gettid) && defined(HAVE_JRAND48)#define DO_JRAND_MIXTHREAD_LOCAL unsigned short jrand_seed[3];#endifstatic int get_random_fd(void){ struct timeval tv; static int fd = -2; int i; if (fd == -2) { gettimeofday(&tv, 0);#ifndef _WIN32 fd = open("/dev/urandom", O_RDONLY); if (fd == -1) fd = open("/dev/random", O_RDONLY | O_NONBLOCK); if (fd >= 0) { i = fcntl(fd, F_GETFD); if (i >= 0) fcntl(fd, F_SETFD, i | FD_CLOEXEC); }#endif srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);#ifdef DO_JRAND_MIX jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF); <=== 崩溃在对thread local 变量 jrand_seed的赋值上
GDB 跟踪调试的时候发现,jrand_seed的地址是一个非法地址,首先想到大概是GCC或GlibC对TLS的支持的问题,如果将jrand_seed修改为非TLS变量或者使用老一点的不使用TLS变量的libuuid,都不会崩溃。最后找到一篇类似问题的报告https://github.com/mkoppanen/php-zmq/issues/11,并且里面提到了一个规避方法:即预先加载libuuid动态库export LD_PRELOAD="/lib64/libuuid.so.1"。持续追查下去,最后发现,这的确是glibc的一个bug,在使用“使用动态加载技术(dlopen),并且使用TLS的时候出现”。为什么我们基于Centos 6.5系统做的系统镜像上没有这个问题呢,原因是:我们后期使用yum upgrade/update更新了系统,glibc也被附带更新了,而新的glibc fix了这个问题。
3 解决办法
碰到这个问题,解决的办法就是更新glibc了,Centos glibc-2.12-1.149已经修复了这个问题。glibc升级的时候需要考虑abi 兼容性的问题,可以使用abidiff或abipkgdiff比较新老glibc兼容性。如果glibc兼容,则可以直接升级,否则要连同系统一起整体升级,并重新编译上层应用。
- libuuid.so 崩溃问题
- 解决 liblzo2.so.2缺失和libuuid.so缺失
- ubuntu-64位 error while loading shared libraries: libuuid.so.1: wrong ELF class: ELFCLASS64
- [Qt creator+Linux]安装UUID(libuuid)以及问题undefined reference to uuid generate
- .so问题
- linux下安装libuuid
- Android 运行崩溃找不到so包解决方案
- 安卓jni的so崩溃调试
- Android 运行崩溃找不到so包解决方案
- linux下安装使用libuuid
- PyRun_SimpleFile()崩溃问题
- PyRun_SimpleFile()崩溃问题
- 问题解决之道----程序崩溃
- 解决QTP崩溃问题
- 解决eclipse崩溃问题
- CString::MakeLower() 崩溃问题
- CString::MakeLower() 崩溃问题
- Release版本崩溃问题
- JVM 调优参数详解(转)
- Android中使用Socket
- [HDU]1166 敌兵布阵 (线段树--单点更新,区间求和)
- LINUX文件编译
- 失踪几个月的程序员又回来了,于是他带来他自己的手机端网站。
- libuuid.so 崩溃问题
- Java面向对象--接口
- 最好用的API调试接口 在线接口测试工具
- JavaScript 注册登录页面的简单实现
- 查看SD卡
- 【BZOJ1059】[ZJOI2007][二分图匹配]矩阵游戏
- 7.5.1 Point-in-Time Recovery Using Event Times 使用Event Times 基于时间点恢复
- Realm for Android快速学习
- 为什么 ++[[]][+[]]+[+[]] = 10 ?