作为系统管理员,我有时会遇到这样的情况,即程序运行异常,而根本不会产生错误或产生无意义的错误消息。
过去 - 在 java 出现之前 - 有两种对策:
我通常strace -f在 Linux 上用于此任务(其他操作系统具有类似的跟踪工具)。现在,虽然这通常适用于任何老式程序,但在java进程上执行相同操作时,跟踪会变得非常模糊。有太多看起来与任何实际操作无关的系统调用,在这样的转储中搜索是很糟糕的。
有没有更好的方法来做到这一点(如果源代码不可用)?
我有两个正在运行的进程实例。其中之一是“吓坏了!” 和打印错误不停地到标准输出。
我想终止损坏的进程,但我必须确保我不会终止错误的进程。它们几乎是同时启动的,使用top我可以看到它们使用的内存和 CPU 量大致相同。我似乎找不到任何表明哪个进程表现不佳的内容。
最安全的做法是找出哪个进程/pid 正在写入 STDOUT。
有没有办法做到这一点?
Bash 有一个有时有用的功能,如果您打开“ -x”选项(我相信符号名称是xtrace),Bash 会在执行时输出脚本的每一行。
我知道有两种方法可以实现这种行为:
set -x-x选项传递给 Bash。有什么方法可以通过环境变量打开此选项吗?
(特别是,我自己没有调用 Bash,所以我无法向它传递任何选项,并且感兴趣的脚本位于压缩存档内,我真的不想重建它。如果我可以设置一个环境变量,它可能会被所有子进程继承......)
联机帮助页说了一些关于 的内容BASHOPTS,但是当我尝试时,Bash 说这是只读的。(感谢您没有在联机帮助页中提及这一点。)
同样,SHELLOPTS似乎也是只读的。
您可以选择与 一起使用哪个 FDBASH_XTRACEFD。但我仍然需要首先打开跟踪。
我知道strace,它对于观察系统调用非常方便。是否有可以跟踪对外部库的调用的等效项?
例如,我正在尝试使用第三方二进制文件调试一些 SSLeay 不当行为,我无法访问其代码(并且开发人员没有响应)。我相信我已经确定了问题所在,但是如果不确切了解签名检查的数据是如何格式化以发送到 SSLeay 的,我就无法对此进行测试。
如果这篇文章有点密集/混乱,请提前道歉,但我很难更好地制定它......基本上,我想研究硬盘写入时会发生什么,我想知道:
更详细地说 - 首先,我使用的操作系统是:
$ 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,我注意到它是根目录下的一个目录/ …
当ltrace用于跟踪系统调用时,我可以看到 fork() 使用 sys_clone() 而不是 sys_fork()。但是我找不到定义它的 linux 源代码。
我的程序是:
#include<stdio.h>
main()
{
int pid,i=0,j=0;
pid=fork();
if(pid==0)
printf("\nI am child\n");
else
printf("\nI am parent\n");
}
Run Code Online (Sandbox Code Playgroud)
而ltrace输出是:
SYS_brk(NULL) = 0x019d0000
SYS_access("/etc/ld.so.nohwcap", 00) = -2
SYS_mmap(0, 8192, 3, 34, 0xffffffff) = 0x7fe3cf84f000
SYS_access("/etc/ld.so.preload", 04) = -2
SYS_open("/etc/ld.so.cache", 0, 01) = 3
SYS_fstat(3, 0x7fff47007890) = 0
SYS_mmap(0, 103967, 1, 2, 3) = 0x7fe3cf835000
SYS_close(3) = 0
SYS_access("/etc/ld.so.nohwcap", 00) = -2
SYS_open("/lib/x86_64-linux-gnu/libc.so.6", 0, 00) = 3
SYS_read(3, "\177ELF\002\001\001", 832) = 832 …Run Code Online (Sandbox Code Playgroud) 有什么方法可以在 FreeBSD 10 上使用 ZFS 找到一些定期写入磁盘(根据 hdd led)的进程(也许将 ZFS 转换为详细日志记录模式)?
lsof 由于磁盘访问时间很短,其他即时聚合统计实用程序似乎无法捕获任何内容。
我正在寻找一种工具,它允许跟踪对 Linux/ARM 中共享库中函数的调用。基本上,我希望能够指定一个命令行并让这个工具生成被调用库函数和传递参数的记录。我想可以为此使用某种形式的函数挂钩。
我知道ltrace,它提供了我需要的功能。但是,ltrace对我不起作用,因为它:
我正在寻找更强大的替代方案。速度不错,但不是我主要关心的问题。首先,我想有一种方法来跟踪可以分析任何(非回避)程序的库调用。
Sysdig 也不能在 ARM 中工作,并且 dtrace 的端口仍然只在 NetBSD 中处于测试阶段。
有没有人知道这种处于可用状态的工具?
我正在探索使用set -x( set +xto unset) in跟踪命令bash:
在展开之后和执行之前,打印简单命令的踪迹,用于命令、case 命令、选择命令和命令及其参数的算术或关联的单词列表。PS4 变量的值被扩展,结果值打印在命令及其扩展参数之前。
现在考虑以下内容,跟踪echo \[-neE\] \[arg …\]带和不带引号的 bash 内置命令的使用:
# set -x # what I typed
# echo 'love' # ...
+ echo love <--(1) the trace
love # the output
# echo love? # note the input contains no quote whatsoever
+ echo 'love?' <--(2) note the trace contains quotes after returning word
love? # i.e. failed to find any file
# echo 'love?' …Run Code Online (Sandbox Code Playgroud) 有没有办法递归地打印出我当前所在的所有本地和远程 shell?
例如,在我的本地机器上,我将 ssh 连接到另一台机器。从那里,我可以切换用户(打开另一个外壳)。然后我再次 ssh 到我的本地机器,等等。更复杂的是,我通常会有多个 shell 选项卡(甚至窗口),所以我通常无法记住我对每个选项卡的跟踪。
我想要的是按照我所在的位置打印出每个会话。或者至少如果我exit是当前的 shell,我会被踢回哪个shell。
在打开多个外壳几天或几周后,我不知道如果我输入exit. 我的 shell 窗口会关闭吗(因为我在“根”shell 中)?我会被踢回另一台服务器吗?
换句话说,我想要我的 SSH 跃点的踪迹。