system server crash//Android 信号

本文深入探讨了Android系统中信号处理的定义、行为及其来源,并详细分析了C++ Crash、Java Crash等现象背后的信号机制,为开发者提供了一种理解系统异常的新视角。
<think> 我们遇到了两个错误: 1. `/system/bin/sh: kill: pidof: arguments must be jobs or process IDs` 2. `/system/bin/sh: kill: system_server: arguments must be jobs or process IDs` 错误原因分析: 命令中的反引号(`)在shell中用于命令替换,即先执行反引号内的命令,然后用命令的输出替换反引号部分。但是,在adb shell环境中,可能由于shell解释器的差异(例如使用的是Android的mksh或其他shell),命令替换的语法可能不被正确支持,或者命令替换中的命令执行失败。 具体到这条命令:`kill -11 `pidof system_server`` 预期执行顺序是: 1. 执行 `pidof system_server` 得到 system_server 进程的PID(一个数字) 2. 将得到的PID替换到 kill 命令中,变成 `kill -11 1234`(假设PID是1234) 然而,实际执行时,`pidof` 命令可能不存在,或者执行失败,导致 `pidof system_server` 这个字符串被直接传递给了kill命令,而kill命令期望的是一个进程ID(数字)或者作业ID(以%开头的字符串)。因此,出现了上述错误。 解决方法: 1. 确保 `pidof` 命令在设备上可用。在Android设备上,`pidof` 可能不是标准命令。我们可以使用 `ps` 命令结合 `grep` 和 `awk`(或 `busybox` 工具)来获取进程ID。 2. 修改命令,使用更通用的方法获取进程ID。 替代方案: 我们可以使用以下命令获取 `system_server` 的PID: `ps -A | grep system_server | awk '{print $2}'` 但是,在Android的shell中,`ps`的输出格式可能不同,且不一定有`awk`。更通用的方法是使用`pgrep`命令(如果可用)或者使用`busybox`。 然而,在标准的Android shell中,可能没有`pgrep`和`awk`。因此,我们尝试使用`ps`和`grep`,并利用`cut`来提取PID(如果可用)。另外,我们也可以使用`procrank`或`toolbox`等工具,但这些不一定在所有设备上都存在。 一个更可靠的方法是使用`ps`命令并指定输出格式。但在Android中,不同版本的`ps`支持不同的参数。我们可以尝试: `ps | grep system_server` 但是,`system_server`是以root权限运行的系统进程,可能需要使用`ps -A`(Android 8.0以上)或者`ps -ef`来查看所有进程。 具体步骤: 1. 首先,我们检查设备上是否有`pidof`命令。在adb shell中执行: pidof system_server 如果返回一个数字,则说明该命令存在。否则,会提示未找到命令。 2. 如果没有`pidof`,我们尝试使用以下命令获取PID: ps -A | grep system_server 在输出中,我们通常可以看到一行,例如: system 1234 1 ... system_server 其中第二列(以空格分隔)是PID。但是,不同的设备`ps`输出格式可能不同(列数可能不同)。我们可以使用`grep`和`tr`、`cut`等工具来提取第二列。 但是,如果设备上没有这些工具,我们可以尝试使用: ps -A -o pid,args | grep system_server | grep -v grep | awk '{print $1}' 或者,如果没有awk,我们可以用: ps -A -o pid,args | grep system_server | grep -v grep | tr -s ' ' | cut -d ' ' -f 2 但这种方法可能不可靠,因为不同设备的`ps`输出格式不同。 3. 另一种方法是使用`procrank`,但需要root权限,而且不是所有设备都有。 考虑到简单性和兼容性,我们可以尝试: kill -11 $(ps -A | grep system_server | grep -o -E '[0-9]+' | head -n1) 解释: - `ps -A`:列出所有进程。 - `grep system_server`:过滤出包含'system_server'的行。 - `grep -o -E '[0-9]+'`:从该行中提取所有数字(进程ID通常在第一列,但这里我们提取所有数字,然后取第一个,因为进程ID是行首的数字)。 - `head -n1`:取第一个数字(即进程ID)。 但是,这个命令依赖于`grep`的`-o`选项和`-E`选项,以及`head`命令。在Android shell中,这些命令通常是可用的(因为Android有toybox或busybox)。 如果设备上使用的是toybox,那么这些命令是支持的。 因此,我们可以将原命令修改为: adb shell "while true; do kill -11 \$(ps -A | grep system_server | grep -o -E '[0-9]+' | head -n1); usleep 3000000; done" 注意:这里我们使用了`$(...)`代替了反引号,它是更现代的语法,但在Android的shell中可能仍然使用`sh`,所以`$(...)`应该被支持。如果不支持,可以换回反引号,但需要正确转义。 但是,在双引号中使用`$()`需要转义,所以写成`\$(...)`。 另一种方法:使用`pidof`的替代命令`pgrep`(如果可用): adb shell "while true; do kill -11 \$(pgrep -f system_server); usleep 3000000; done" 但是,`pgrep`在Android中不一定存在。 所以,我们优先使用`ps`的方法。 但是,还需要注意:如果`ps -A`不可用(旧版Android可能没有),可以尝试`ps`(不带参数)或者`ps -ef`。 在旧版Android中,我们可以使用: ps | grep system_server 因为`system_server`是系统进程,通常运行在root用户下,所以使用`ps`(不带参数)可能不会显示,因此建议使用`ps -A`(显示所有进程)或者`ps -ef`(显示完整格式的进程列表)。 因此,我们最终修改后的命令为: adb shell "while true; do kill -11 \$(ps -A | grep system_server | grep -o -E '[0-9]+' | head -n1); usleep 3000000; done" 如果仍然无法获取PID,请检查`ps -A`的输出,并调整grep的表达式。 此外,还有一个错误可能是:`usleep`命令不存在。在Android中,`usleep`可能位于`/system/bin/usleep`,但并非所有设备都提供。我们可以使用`sleep`命令代替,但`sleep`的最小单位是秒(支持小数)。例如,睡眠3秒可以写成`sleep 3`。 所以,如果`usleep`不可用,我们可以改用: adb shell "while true; do kill -11 \$(ps -A | grep system_server | grep -o -E '[0-9]+' | head -n1); sleep 3; done" 注意:`sleep`在Android shell中通常是可用的。 总结步骤: 1. 使用adb shell连接设备,单独测试获取system_server进程ID的命令: ps -A | grep system_server | grep -o -E '[0-9]+' | head -n1 看看是否输出一个数字(即进程ID)。 2. 如果输出为空,则可能需要调整命令。可以尝试: ps -A | grep system_server 观察输出,然后调整提取PID的方式。 3. 如果上述命令无法提取PID,可以考虑使用: ps -ef | grep system_server | grep -v grep | awk '{print $2}' 但需要设备有awk。 4. 如果设备没有`grep`或者`head`等工具,可能需要安装busybox,或者使用更简单的循环。 由于问题中已经报错,主要原因是`pidof`命令不存在,所以我们使用`ps`替代方法。 因此,修改后的命令为: adb shell "while true; do kill -11 \$(ps -A | grep system_server | grep -o -E '[0-9]+' | head -n1); sleep 3; done" 注意:如果`kill`命令执行时,PID为空,那么会报错:`kill: not enough arguments`。因此,我们最好在PID获取失败时跳过本次操作。 但是,由于我们的命令是循环执行,即使某次获取失败,下一次可能成功(例如,有时system_server可能在重启过程中短暂不存在),所以可以忽略。 如果担心空PID的情况,可以加一个条件判断: adb shell "while true; do PID=\$(ps -A | grep system_server | grep -o -E '[0-9]+' | head -n1); if [ ! -z \"\$PID\" ]; then kill -11 \"\$PID\"; fi; sleep 3; done" 这个命令在获取到PID不为空时才执行kill。 综上所述,我推荐使用带有条件判断的版本,以避免PID为空时kill报错。 最终命令: adb shell "while true; do PID=\$(ps -A | grep system_server | grep -o -E '[0-9]+' | head -n1); if [ ! -z \"\$PID\" ]; then kill -11 \"\$PID\"; fi; sleep 3; done" 请尝试这个命令。 如果设备上的`ps`输出格式不同,可能需要调整提取PID的方法。请根据实际`ps`输出进行调整。 关于错误2:`/system/bin/sh: kill: system_server: arguments must be jobs or process IDs`,这个错误是因为`pidof system_server`没有返回数字,而是原样返回了命令,所以kill把'system_server'当成了参数,从而报错。使用上述方法后,应该能够正确获取PID,从而避免这个错误。 另外,需要注意的是,杀死system_server进程会导致系统重启(系统服务重启),所以请确保在测试设备上执行,避免数据丢失。 如果上述命令仍然报错,可能是因为设备上的shell不支持某些功能,请提供设备上的`ps -A`输出示例,以便进一步调整命令。 </think> ### 解决 adb shell 命令报错问题 您遇到的错误 `/system/bin/sh: kill: pidof: arguments must be jobs or process IDs` 和 `/system/bin/sh: kill: system_server: arguments must be jobs or process IDs` 是由于命令替换语法问题导致的。下面是详细分析和解决方案: #### 错误原因分析 1. **命令替换语法错误** 原命令中使用反引号 ``` `pidof system_server` ``` 进行命令替换,但 Android 的默认 shell (mksh) 对命令替换的处理与标准 Bash 不同: ```bash # 错误写法 kill -11 `pidof system_server` ``` 在 Android shell 中,反引号内的整个字符串 `pidof system_server` 被当作单个参数传递给 `kill`,而不是先执行 `pidof` 命令获取 PID[^1]。 2. **pidof 工具的可用性问题** 部分 Android 设备可能未预装 `pidof` 命令,导致命令执行失败(尤其在新版 Android 中)。 #### 解决方案 ##### 方法 1:使用正确的命令替换语法 将反引号替换为 `$()` 语法,这是 Android shell 支持的命令替换方式: ```bash adb shell "while true; do kill -11 \$(pidof system_server); sleep 3; done" ``` * **修改说明**: - `$(pidof system_server)` 正确执行命令替换 - `sleep 3` 替代 `usleep 3000000`(兼容性更好) - 使用反斜杠 `\$` 避免变量在本地 shell 解析 ##### 方法 2:使用 ps + grep 替代 pidof 如果设备不支持 `pidof`,改用标准进程查询方式: ```bash adb shell "while true; do kill -11 \$(ps -A | grep system_server | grep -o -E '[0-9]+' | head -n1); sleep 3; done" ``` * **工作流程**: 1. `ps -A`:列出所有进程 2. `grep system_server`:过滤目标进程 3. `grep -o -E '[0-9]+'`:提取 PID 数字 4. `head -n1`:取第一个结果 ##### 方法 3:添加错误处理机制 增加 PID 有效性检查,避免空值错误: ```bash adb shell "while true; do PID=\$(pidof system_server); if [ -n \"\$PID\" ]; then kill -11 \"\$PID\"; fi; sleep 3; done" ``` #### 验证步骤 1. **单独测试命令替换**: ```bash adb shell "echo \$(pidof system_server)" ``` 应返回数字 PID(如 `1234`),而非命令文本 2. **检查 pidof 可用性**: ```bash adb shell "type pidof" ``` 若返回 `not found`,需使用方法 2 3. **完整命令测试**: ```bash adb shell "PID=\$(ps -A | grep system_server | grep -o -E '[0-9]+' | head -n1); echo \$PID" ``` #### 注意事项 1. **权限要求** 需 root 权限设备才能杀死 `system_server` 进程,普通设备会报 `Operation not permitted`[^1] 2. **系统稳定性** 频繁杀死 `system_server` 会导致系统循环重启,仅限测试设备使用[^3] 3. **备用方案** 对于无 root 设备,可使用系统崩溃测试命令: ```bash adb shell am crash com.android.systemui ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值