sshd 启动失败问题排查总结(没有core)
1. 现象
执行
/usr/bin/dlz_sshd -D -e -ddd -f /mnt/mtd/openssh6/sshd_config
时,前台无任何日志输出。(dlz_ssh
,dlz_sftp
,dlz_ssh-keygen
等工具能正确运行并输出 usage ,表明工具链和大部分 OpenSSH 功能代码是可用的)
2. 用 gdb 启动并捕获崩溃点
如果程序退出但没有任何 stderr 输出,gdb 能直接给出崩溃的堆栈(如果是 segfault)。
gdb ./dlz_sshd
# 在 gdb 提示符下:
(gdb) run -D -e -ddd -f /mnt/mtd/openssh6/sshd_config
# 程序崩溃后:
(gdb) bt full
(gdb) info sharedlibrary
但是发现没有core
3. gdb 不可用或无 core,运行时用 strace 跟踪系统调用
strace 能知道在哪个系统调用失败或 exit:
strace -o strace.log ./dlz_sshd -D -e -ddd -f /mnt/mtd/openssh6/sshd_config
tail -n 200 strace.log
strace 的最后几行信息已经非常关键:
socket(AF_UNIX, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/tmp/uinetsck.socket"}, 110) = 0
sendto(3, "\1\t\0\0\2\0\1\t", 8, 0, NULL, 0) = 8
recvfrom(3, "\0\0\0\0", 4, 0, NULL, NULL) = 4
close(3) = 0
msgget(0x9010002, 000) = 19890183
semget(0x9010002, 1, 000) = 19529735
...
exit_group(255) = ?
现象总结
没有 segfault,所以程序是主动 exit(255)。
运行逻辑:
它先通过 Unix 域 socket
/tmp/uinetsck.socket
连接了一个 协议栈代理/管理进程(我们自研的 sros 网络栈 daemon)。然后通过
msgget
/semget
进入了 System V IPC 通道,发送了几条消息(msgsnd
)。收到响应后,它检查返回内容,发现不满足预期(
recvfrom
收到全零,或者 IPC 回复错误),于是直接exit(255)
。OpenSSH 在初始化 socket/bind 失败时,选择了
exit(255)
,这是典型的 sshd 退出码。
结论
我的 dlz_sshd
并不是崩溃,而是 因为调用的 sros 套接字接口/代理返回了错误结果,导致 sshd 直接退出。
然后就是socket替换不完整导致的该问题:
自研协议栈接口替换未完成
OpenSSH 默认走 socket(AF_INET),但代码已被替换成 SROS 接口。
在替换过程中,
listen
/accept
没有被正确调用,导致初始化失败。