一次诡异的 fork 死锁排查:最终定位到 glibc 2.17 的隐藏并发问题
某日客户反馈,软件在 CentOS 7 上突然离线。
登录机器后发现进程还在,但 CPU 使用率为 0,也没有任何日志输出。用 gdb 附加上去一看,程序已经陷入死锁。
更诡异的是,卡住的位置竟然是 fork()。
某日客户反馈,软件在 CentOS 7 上突然离线。
登录机器后发现进程还在,但 CPU 使用率为 0,也没有任何日志输出。用 gdb 附加上去一看,程序已经陷入死锁。
更诡异的是,卡住的位置竟然是 fork()。
平时逛到一些有意思、或者确实能省事的网站,随手记在这里。按用途分类,方便以后翻找;发现更好的同类站再补充或替换。
编译、调试、查文档、在线跑代码、看日志之类。
cargo。本文记录 YouCompleteMe(YCM)的安装与 C/C++ 补全配置,并留存 .vimrc、compile_commands.json 等要点。行文按「先装起来 → 再配工程 → 再调 clangd → 最后理解 LSP」的顺序展开。安装方式基于 vim-plug + install.py --clangd-completer;Neovim 用户可将插件目录改为 ~/.local/share/nvim/plugged。YCM 详见 ycm-core/YouCompleteMe,C/C++ 语言服务详见 clangd。
Linux 在 /etc/shadow 第二列保存散列后的密码。同一个明文密码,每次生成的散列值往往不同——这不是 Python 或命令用错了,而是因为引入了 salt(盐)。
用 Python 的 crypt 模块可以快速生成 SHA-512 散列:
1 | python3 -c 'import crypt; print(crypt.crypt("test", crypt.mksalt(crypt.METHOD_SHA512)))' |
每次执行结果都不同,但都可以直接写入 /etc/shadow 作为该用户的密码。用 passwd 修改同一账户密码时,生成的散列值同样每次都不一样。
在开发中时不时会在代码中调用系统命令,Linux 中调用系统命令的方法比较多。是否需要获取命令的输出也需要考虑。
exec 函数系列是指以 exec 为开头用来执行Shell命令的几个函数。
1 | #include <unistd.h> |
此文不介绍sudoers文件的配置方法,只是简单介绍sudo工作流程。
工作流程如下图,第一次用markdown写流程图,不太精细。
flowchart TD
st([用户执行sudo])
is_have_cookie{检查 /var/run/sudo/ts 文件夹下是否有认证文件}
cookie_is_expire{检查认证文件是否有效}
is_in_sudoers{是否在 /etc/sudoers 文件中}
input_passwd[输入密码]
op[执行并返回结果]
e([退出])
st --> is_have_cookie
is_have_cookie -- yes --> cookie_is_expire
is_have_cookie -- no --> input_passwd
cookie_is_expire -- yes --> is_in_sudoers
cookie_is_expire -- no --> input_passwd
input_passwd --> is_in_sudoers
is_in_sudoers -- yes --> op
is_in_sudoers -- no --> e
op --> e