有没有办法在不实际杀死进程的情况下为进程获取核心转储(或类似的东西)?我有一个在嵌入式系统上运行的多线程 python 进程。而且我希望能够在正常条件下(即需要运行其他进程)获得进程的快照,但是我没有足够的内存来连接 gdb(或在 gdb 下运行它)而没有 python 进程作为唯一一个运行。
我希望这个问题是有道理的。
如果这篇文章有点密集/混乱,请提前道歉,但我很难更好地制定它......基本上,我想研究硬盘写入时会发生什么,我想知道:
更详细地说 - 首先,我使用的操作系统是:
$ uname -a
Linux mypc 2.6.38-16-generic #67-Ubuntu SMP Thu Sep 6 18:00:43 UTC 2012 i686 i686 i386 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
所以,我有以下简单的(例如,跳过通常的操作失败检查)用户空间 C 程序,wtest.c:
#include <stdio.h>
#include <fcntl.h> // O_CREAT, O_WRONLY, S_IRUSR
int main(void) {
char filename[] = "/tmp/wtest.txt";
char buffer[] = "abcd";
int fd;
mode_t perms = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
fd = open(filename, O_RDWR|O_CREAT, perms);
write(fd,buffer,4);
close(fd);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我用gcc -g -O0 -o wtest wtest.c. 现在,由于我正在尝试写入/tmp,我注意到它是根目录下的一个目录/ …
如果应用程序在 Windows 中崩溃,我们可以检查管理工具中的事件查看器以查看崩溃的原因。有时它有有用的信息,而其他人没有,但这是一个开始。
在 linux 中,如果一个应用程序(任何)崩溃了,人们如何开始跟踪发生了什么?
是否有一些中央日志或类似的东西?
我有一个 USB 游戏手柄,我想查看并检查该外围设备实际发送到我的 PC/内核的信号和命令:我该怎么做?
我假设像
cat /dev/bus/usb/006/003
Run Code Online (Sandbox Code Playgroud)
足够了,但显然这个命令会立即返回并打印一些不可读的编码字符。
有没有办法“调试”这样的 USB 设备?
是否有与Solaris 实用程序的-T和-U选项truss在 Linux 上执行的等效项。
这些是指定一个系统调用 ( -T) 或库函数 ( -U),当被跟踪应用程序调用时会导致它停止。
或者,换句话说,我希望被跟踪的应用程序启动的任何进程在执行给定的系统调用或给定的共享库函数调用后立即停止(就像被 SIGSTOP 杀死一样)。
strace并且ltrace在 Linux 上提供了 Solaris 的许多功能集truss,但他们似乎没有这样做。
例如:
truss -f -T open cmd
Run Code Online (Sandbox Code Playgroud)
会是这样strace -f cmd,只是如果在执行过程中cmd或任何其后代做任何open系统调用时,它会立即停止(我可以在我方便以后恢复它)
在某些情况下,我可以使用gdb's catch syscall,但我正在寻找一种可以方便地跟踪分叉并继续为所有分叉进程执行此操作的解决方案,即使在execves之后也继续执行此操作。
我似乎记得一些实用程序提供了相同的功能,甚至是一个(或同一实用程序的选项)在某些远程系统调用之间的单步应用程序,但我的记忆力让我失望,我什至无法确定那是在 Linux 上。
我有一个脚本launch.sh,它作为另一个用户执行,以便创建具有正确所有者的文件。如果最初传递给脚本,我想将 -x 传递给此调用
if [ `whoami` == "deployuser" ]; then
... bunch of commands that need files to be created as deployuser
else
echo "Respawning myself as the deployment user... #Inception"
echo "Called with: <$BASH_ARGV>, <$BASH_EXECUTION_STRING>, <$->"
sudo -u deployuser -H bash $0 "$@" # How to pass -x here if it was passed to the script initially?
fi
Run Code Online (Sandbox Code Playgroud)
我已经阅读了bash 调试页面,但似乎没有明确的选项可以说明原始脚本是否使用-x.
我喜欢set -x在脚本中使用来显示正在发生的情况,特别是如果脚本将在 CI/CD 管道中运行并且我可能需要事后调试一些故障。
这样做的一个烦恼是,如果我想向用户回显一些文本(例如,状态消息或"I'm starting to do $X"),那么该消息会输出两次 - 一次用于echo回显命令本身,然后一次作为该echo命令的输出。
有什么好方法可以让这个变得更好?一种解决方案是这样的:
set -x
... bunch of normal commands that get echoed
(
# Temporarily don't echo, so we don't double-echo
set +x
echo "Here is my status message"
)
... rest of commands get echoed again
Run Code Online (Sandbox Code Playgroud)
但这样做的两个问题是
set +x也呼应了,这是不可取的。还有其他效果好的选择吗?
当我关闭笔记本电脑的盖子时,我遇到了奇怪的错误 - 系统死机(对按键没有反应,ssh 没有响应)并显示一些奇怪的颜色效果。内核日志(重新启动后)什么也没显示。我的问题是 - 如何调试它?也许有一种方法可以跟踪上次调用的内核函数或类似的东西?
我知道printf需要操作系统的帮助才能完成其工作。
我也知道printf在 Linux 源代码中不起作用,因为没有库。所以我们必须printk进行调试。
printk当操作系统仍在启动时如何工作?
有时添加真的很方便
set -x
Run Code Online (Sandbox Code Playgroud)
到脚本顶部以在执行之前显示所有命令。
创建具有体面输出的脚本只有一个缺点:我不知道如何以这种方式将文本输出添加到脚本中。如果我使用
echo 'some comment'
Run Code Online (Sandbox Code Playgroud)
它会导致打印结果翻倍:
+ echo 'some comment'
some comment
Run Code Online (Sandbox Code Playgroud)
如果我使用#它根本不显示。
如何添加打印出来的注释echo?如果我使用set -x?