跳转至

生产问题排查

1 stack资源限制导致进制启动失败

  • 问题原因:stack size 设置成 unlimited 后导致启动失败,设置一个准确值启动成功。具体原因未分析出。
  • 分析过程:
  • 在生产环境上启动脚本,显示执行失败,查看日志,没有任何信息,打开debug日志,依然没有有效日志产生;查看core dump目录下是否产生core dump文件,没有。
  • 直接启动进程,进程并没有返回任信息。
  • gdb调试启动进程,由于编译器的优化,效果不理想,进入子进程无法继续跟踪。
  • 查看系统日志/var/log/messages,grep 过滤进程A相关日志,发现有进程异常退出日志,必然会产生core dump文件,于是使用ulimit -a检查core dump文件大小等于0,再查看/proc/sys/kernel/core_pattern,重新设置core dump文件生成位置echo "/tmp/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
  • 重新启动进程A,查看core dump文件,gdb查看,发现 core位置是在对一个栈内存数组memset时出现问题。按往常经验(栈内存访问出错很少见),怀疑是其它地方导致的问题。多次启动进程A,获取多个core dump文件,查看,依然是core在memset 栈内存数组上。
  • 开始怀疑是栈大小问题,通过ulimit -a查看最大栈大小,结果是unlimited,所以排除了栈的问题。
  • 询问其它同事,有没有修改过系统环境,反馈修改过stack大小为unlimited,原先是512000。怀疑还是和这个stack大小有关,查阅资料,发现有些人遇到过设置stack size =unlimited后,进程异常问题。
  • 使用ulimit -s 512000恢复stack size后,再次启动进程A,进程启动成功。
  • 询问同事,是否可以将此参数恢复,得到的答案是否到的,所以,没有去修改/etc/security/limits.conf文件使永久生效;采用启动进程A前,先ulimit -s 512000,再启动进程方式。
  • 问题解决:在启动进程前,使用ulimit -s 131072设置stack大小为一个具体值,再启动进程。

2 开发问题排查

1 malloc、free 后进程内存没有降低?

  • 问题原因:频繁的使用 malloc 分配小内存(默认 128k 由 brk 分配的),再 free,某种情况下,导致堆内碎片过多,堆顶一直往后移。
  • 解决办法:
    • 使用 malloc_trim (0) 强制回收堆顶内存(测试显示对内碎片也被回收,这个原因不清楚)。
    • 使用内存池管理。 参考资料

2 使用了线程不安全函数,导致偶发问题

3 编译 attr 源码包解决 getfattr 乱码问题

  • 问题原因:
  • 分析过程:

4 memset 含 stl 类型数据导致 core

  • 问题原因:stl 类型可能内部有指针,memset 把这些指针赋值为 0 了,导致访问数据失败。
  • 分析过程:

3 编译问题

1 使用 gcc 而不是 g++编译,依然按 c++编译

  • 问题原因:原编译命令如 gcc test.c ;指定 gcc,会通过文件名后缀来采用何种编译器。而测试编译的文件名后缀是 . cc 这就导致没有按预期的 c 编译。
  • 解决办法:
    1. 文件名后缀改为 .c,示例如 gcc test.c
    2. 编译选项指定 c 编译,选项为 -xc,示例如 gcc -xc test.cc

2 ‘struct statvfs’在形参表内部声明

  • 错误输出
test.h:52:49: 警告:‘struct statvfs’在形参表内部声明 [默认启用]
 int adapter_statfs(const char *pathname, struct statvfs *stbuf, NCDFS *sp);

ncdfs.h:52:49: 警告:它的作用域仅限于此定义或声明,这可能并不是您想要的 [默认启用]
  • 问题原因:statvfs 没有在 adapter_statfs 函数之外定义。
  • 解决办法:
    1. 包含 statvfs 所在的头文件,如 #include<sys/statvfs.h>
    2. 前置声明,如 struct statvfs;