Linux系统小技巧(6):刀锋组合-strace和wireshark工具

简介: strace是个宅男,强力手段局限于单机之内。wireshark对包的进出条分缕析,但是对于包的后半生却缺少足够的盯梢能力。但现在是云起潮涌的时代,举目所见,分布式比比皆是。那么,在此情形下如何发挥两个强大工具的能力呢?

首先声明下,此处wireshark,可以替换为tcpdump。同样,[strace]偶尔也可以替换为[ltrace],只要熟悉库函数就好。

wireshark和[strace],对于黑客而言,都是工具箱中的必备工具。有过排查和诊断经历的工程师,谁没有抓包和分析包的经历呢?

相对而言,[strace]的名气要小一些,毕竟有意愿、有能力追踪并且能够分析进程执行路径的不多。而且常见的[系统调用]也有二三十个。

系统调用如此强力,why?

让我们先明确下为什么[strace]工具颇具威力,看图

unix_system_block

虽然Linux已经足够复杂,而且,文件子系统和进程控制子系统间还有复杂交互。因此,上面这张图只能说大致写意而已。但是,这张图还是能把[系统调用]的位置和功能表达出来

The system call is the fundamental interface between an application and the Linux kernel.
系统调用是应用和内核之间的根本接口。

从其所处的位置看,对于用户空间的应用而言,无论用户空间的应用是事件触发者还是某些内核事件的被动响应者,用户空间和内核对因某个事件而进行的交互,都会经过[系统调用]这一层。因此,追踪和分析这一层的数据,对于诊断用户空间进程和系统交互而引致的问题,是足够的。对于诊断用户空间应用自身的问题,除非非常特殊的情况(hello world之类的简单程序?很难想象一个有用的应用能够不调用任何系统调用),否则,退一步说,至少也足以提供下一步的排查线索。

为什么要组合使用strace和wireshark?

现在是网络时代。但是[strace]能够cover的范围却局限在一台单机之内。我们需要工具来扩展[strace]覆盖的范围。免费、自由的wireshark无疑是[strace]的最佳队友。如果追踪进程执行路径同时,同时抓包,那么,我们就把[strace]从只能覆盖一台单机中释放了出来。

当然,让[strace]和wireshark联合作战,并非没有代价。首先,你得了解(最好是熟悉)常见系统调用。再者,要能在[strace]和wireshark的输出上建立足够联系。毫无疑问,时间是最好的媒介之一。要[strace]也给出时间戳,我们可以这样来执行strace

strace -f -ff -s 256 -tt -o strace.log your_program

如果需要每个系统调用消耗的时间,可以增加-T选项

strace -f -ff -s 256 -tt -T -o strace.log your_program

实际案例

举个例子。下图就是通过时间戳,把包重传和线程的行为联系了起来。通过这一步,还可以把线程行为向业务逻辑映射,从业务层面上解释线程行为。

需要了解哪些系统调用?

但是,从捕捉到的系统调用分析进程执行路径,不掌握一部分常见的系统调用,肯定是不行的。那么,又那些系统调用我们需要掌握呢?

首先,得熟悉如何查看[manpages]。有需要可以迅速man下。

除此之外,还需要掌握30个左右的常见系统调用。我们以提问的方式,把这些系统调用列出来,供大家参考

方便练习和实验的demo

现在的工具,甚至是echo,因为跨平台、维持历史兼容性、各种选项支持等原因已经足够复杂。这里我们提供一个demo供大家实战。

这是个demo shell,大家可以按照需要编译之,而后使用strace追踪之。

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>

int parse_inputs(char *buf, char **argv);
int usage();

int main(int argc, char **argv)
{
    int rv = 0;
    int pid, status;
    long input_max_len;
    char *buf = NULL;
    char **cmd = NULL;

    if (argc > 1) {
      usage();
      goto out;
    }

    input_max_len = sysconf(_SC_LINE_MAX);
    buf = malloc(input_max_len * sizeof(*buf));
    cmd = malloc(input_max_len * sizeof(*cmd));
    if (buf == NULL || cmd == NULL) {
        rv = 1;
        fprintf(stderr, "failed to alloc memory\n");
        goto out;
    }

      get_cmd:
    fprintf(stdout, "[demo-shell] ");
    if (parse_inputs(buf, cmd)) {
        goto out;
    } else {
        goto run_cmd;
    }

      run_cmd:
    pid = fork();
    if (pid < 0) {
        perror("fork");
        rv = 1;
        goto out;
    }

    if (pid) {
        if (wait(&status) == -1) {
            perror("wait");
            rv = 1;
            goto out;
        }
        goto get_cmd;
    } else {
        if (execvp(cmd[0], cmd) < 0) {
            rv = 1;
            goto out;
        }
    }

      out:
    if (buf) {
        free(buf);
    }
    if (cmd) {
        free(cmd);
    }
    return rv;
}

/*
 * suppose we typed the command 'ls -l', 
 *
 *   loc     len
 *    |       |
 *    v       v
 *  .---.---.---.---.---.-----.---.---.---
 *  | l | s |   |   |   |     |   |    |
 *  .___.___.___.___.___._____.____.___.___
 *
 * then
 *
 *               loc      len
 *                |        |
 *                v        v
 *  .---.---.---.---.---.-----.---.---.---
 *  | l | s |   | - | l | \r |   |    |
 *  .___.___.___.___.___.____.____.___.___
 */
int parse_inputs(char *buf, char **argv)
{
    int c;
    int rv = 0;
    int len = 0;
    int loc = 0;
    int idx = 0;
    while (1) {
        c = getchar();
        if (c == EOF) {
            rv = -1;
            goto out;
        } else if (c == '\n') {
            if (loc < len) {
                buf[len] = '\0';
                argv[idx] = &buf[loc];
                loc = len + 1;
                idx += 1;
            }
            argv[idx] = (char *) NULL;
            goto out;
        } else if (c == ' ') {
            if (loc < len) {
                buf[len] = '\0';
                argv[idx] = &buf[loc];
                loc = len + 1;
                idx += 1;
            } else {
                continue;
            }
        } else {
            buf[len] = c;
        }
        len += 1;
    }
      out:
    return rv;
}

int usage()
{
  int rv = 0;
  fprintf(stdout, "./demo-shell\n");
  return rv;
}

比如,为了尽可能的能和源码对照,我们可以这么实验

cc -O0 -o demo-shell demo-shell.c
[ -d strace-log ] || mkdir strace-log
strace -o strace-log/log -f -ff -tt -s 64 ./demo-shell

实际运行的结果如下

[root@demo lab]# ls
demo-shell.c
[root@demo lab]# cc -O0 -o demo-shell demo-shell.c
[root@demo lab]# [ -d strace-log ] || mkdir strace-log
[root@demo lab]# ls
demo-shell  demo-shell.c  strace-log
[root@demo lab]# strace -o strace-log/log -f -ff -tt -s 64 ./demo-shell
[demo-shell] ls
demo-shell  demo-shell.c  strace-log
[demo-shell] pwd
/root/bf/work/lab
[demo-shell] ls strace-log
log.20541  log.20542  log.20545  log.20549
[demo-shell] [root@demo lab]#

实验数据

我们也给出log.20541和log.20542的内容,供不能编译实验的同学使用

[root@demo lab]# cat strace-log/log.20541
09:35:17.039887 execve("./demo-shell", ["./demo-shell"], [/* 22 vars */]) = 0
09:35:17.040893 brk(0)                  = 0x1432000
09:35:17.041053 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17e60f5000
09:35:17.041249 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
09:35:17.041487 open("/etc/ld.so.cache", O_RDONLY) = 3
09:35:17.041681 fstat(3, {
   st_mode=S_IFREG|0644, st_size=41496, ...}) = 0
09:35:17.041878 mmap(NULL, 41496, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f17e60ea000
09:35:17.042049 close(3)                = 0
09:35:17.042277 open("/lib64/libc.so.6", O_RDONLY) = 3
09:35:17.042459 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\356\1\2559\0\0\0@\0\0\0\0\0\0\0000a\35\0\0\0\0\0\0\0\0\0@\0008\0\n\0@\0N\0M\0"..., 832) = 832
09:35:17.042652 fstat(3, {
   st_mode=S_IFREG|0755, st_size=1930416, ...}) = 0
09:35:17.042831 mmap(0x39ad000000, 3750184, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39ad000000
09:35:17.043044 mprotect(0x39ad18a000, 2097152, PROT_NONE) = 0
09:35:17.043209 mmap(0x39ad38a000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18a000) = 0x39ad38a000
09:35:17.043384 mmap(0x39ad390000, 14632, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x39ad390000
09:35:17.043545 close(3)                = 0
09:35:17.043710 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17e60e9000
09:35:17.043906 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17e60e8000
09:35:17.044075 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17e60e7000
09:35:17.044240 arch_prctl(ARCH_SET_FS, 0x7f17e60e8700) = 0
09:35:17.044518 mprotect(0x39ad38a000, 16384, PROT_READ) = 0
09:35:17.044693 mprotect(0x39ace20000, 4096, PROT_READ) = 0
09:35:17.044869 munmap(0x7f17e60ea000, 41496) = 0
09:35:17.045193 brk(0)                  = 0x1432000
09:35:17.045353 brk(0x1453000)          = 0x1453000
09:35:17.045533 fstat(1, {
   st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
09:35:17.045698 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17e60f4000
09:35:17.045864 fstat(0, {
   st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
09:35:17.046043 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f17e60f3000
09:35:17.046220 write(1, "[demo-shell] ", 13) = 13
09:35:17.046387 read(0, "ls\n", 1024)   = 3
09:35:18.923214 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f17e60e89d0) = 20542
09:35:18.924211 wait4(-1, [{
   WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 20542
09:35:18.953091 --- SIGCHLD {
   si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20542, si_status=0, si_utime=0, si_stime=0} ---
09:35:18.953242 write(1, "[demo-shell] ", 13) = 13
09:35:18.953487 read(0, "pwd\n", 1024)  = 4
09:35:21.202256 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f17e60e89d0) = 20545
09:35:21.203348 wait4(-1, [{
   WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 20545
09:35:21.213873 --- SIGCHLD {
   si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20545, si_status=0, si_utime=0, si_stime=0} ---
09:35:21.213991 write(1, "[demo-shell] ", 13) = 13
09:35:21.214215 read(0, "ls strace-log\n", 1024) = 14
09:35:30.611217 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f17e60e89d0) = 20549
09:35:30.611983 wait4(-1, [{
   WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 20549
09:35:30.639174 --- SIGCHLD {
   si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20549, si_status=0, si_utime=0, si_stime=0} ---
09:35:30.639284 write(1, "[demo-shell] ", 13) = 13
09:35:30.639495 read(0, "# ctrl + d\n", 1024) = 11
09:35:43.687289 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f17e60e89d0) = 20553
09:35:43.688445 wait4(-1, [{
   WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 20553
09:35:43.692210 --- SIGCHLD {
   si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=20553, si_status=1, si_utime=0, si_stime=0} ---
09:35:43.692356 write(1, "[demo-shell] ", 13) = 13
09:35:43.692547 read(0, "", 1024)       = 0
09:35:47.231231 exit_group(0)           = ?
09:35:47.231743 +++ exited with 0 +++
[root@demo lab]#

看看子进程(运行了ls命令)的strace日志

[root@demo lab]# cat strace-log/log.20542
09:35:18.924010 execve("/usr/local/sbin/ls", ["ls"], [/* 22 vars */]) = -1 ENOENT (No such file or directory)
09:35:18.924441 execve("/usr/local/bin/ls", ["ls"], [/* 22 vars */]) = -1 ENOENT (No such file or directory)
09:35:18.924759 execve("/sbin/ls", ["ls"], [/* 22 vars */]) = -1 ENOENT (No such file or directory)
09:35:18.925089 execve("/bin/ls", ["ls"], [/* 22 vars */]) = 0
09:35:18.925901 brk(0)                  = 0x2594000
09:35:18.926162 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f874a9aa000
09:35:18.926375 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
09:35:18.926580 open("/etc/ld.so.cache", O_RDONLY) = 3
09:35:18.926757 fstat(3, {
   st_mode=S_IFREG|0644, st_size=41496, ...}) = 0
09:35:18.926919 mmap(NULL, 41496, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f874a99f000
09:35:18.927074 close(3)                = 0
09:35:18.927330 open("/lib64/libselinux.so.1", O_RDONLY) = 3
09:35:18.927505 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0PY\200\2569\0\0\0@\0\0\0\0\0\0\0 \337\1\0\0\0\0\0\0\0\0\0@\0008\0\10\0@\0\37\0\36\0"..., 832) = 832
09:35:18.927697 fstat(3, {
   st_mode=S_IFREG|0755, st_size=124640, ...}) = 0
09:35:18.927903 mmap(0x39ae800000, 2221912, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39ae800000
09:35:18.928123 mprotect(0x39ae81d000, 2093056, PROT_NONE) = 0
09:35:18.928296 mmap(0x39aea1c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c000) = 0x39aea1c000
09:35:18.928492 mmap(0x39aea1e000, 1880, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x39aea1e000
09:35:18.928673 close(3)                = 0
09:35:18.928838 open("/lib64/librt.so.1", O_RDONLY) = 3
09:35:18.929059 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240!@\2569\0\0\0@\0\0\0\0\0\0\0P\260\0\0\0\0\0\0\0\0\0\0@\0008\0\t\0@\0)\0(\0"..., 832) = 832
09:35:18.929256 fstat(3, {
   st_mode=S_IFREG|0755, st_size=47760, ...}) = 0
09:35:18.929432 mmap(0x39ae400000, 2128816, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39ae400000
09:35:18.929605 mprotect(0x39ae407000, 2093056, PROT_NONE) = 0
09:35:18.929771 mmap(0x39ae606000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x39ae606000
09:35:18.929984 close(3)                = 0
09:35:18.930221 open("/lib64/libcap.so.2", O_RDONLY) = 3
09:35:18.930446 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\23@\2639\0\0\0@\0\0\0\0\0\0\0\310B\0\0\0\0\0\0\0\0\0\0@\0008\0\6\0@\0\36\0\35\0"..., 832) = 832
09:35:18.930631 fstat(3, {
   st_mode=S_IFREG|0755, st_size=19016, ...}) = 0
09:35:18.930808 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f874a99e000
09:35:18.930997 mmap(0x39b3400000, 2111776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39b3400000
09:35:18.931188 mprotect(0x39b3404000, 2093056, PROT_NONE) = 0
09:35:18.931387 mmap(0x39b3603000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x39b3603000
09:35:18.931586 close(3)                = 0
09:35:18.931768 open("/lib64/libacl.so.1", O_RDONLY) = 3
09:35:18.931986 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\36\300\2679\0\0\0@\0\0\0\0\0\0\0X|\0\0\0\0\0\0\0\0\0\0@\0008\0\7\0@\0\37\0\36\0"..., 832) = 832
09:35:18.932194 fstat(3, {
   st_mode=S_IFREG|0755, st_size=33816, ...}) = 0
09:35:18.932380 mmap(0x39b7c00000, 2126416, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39b7c00000
09:35:18.932578 mprotect(0x39b7c07000, 2093056, PROT_NONE) = 0
09:35:18.932778 mmap(0x39b7e06000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x39b7e06000
09:35:18.933040 close(3)                = 0
09:35:18.933337 open("/lib64/libc.so.6", O_RDONLY) = 3
09:35:18.933590 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\356\1\2559\0\0\0@\0\0\0\0\0\0\0000a\35\0\0\0\0\0\0\0\0\0@\0008\0\n\0@\0N\0M\0"..., 832) = 832
09:35:18.933849 fstat(3, {
   st_mode=S_IFREG|0755, st_size=1930416, ...}) = 0
09:35:18.934076 mmap(0x39ad000000, 3750184, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39ad000000
09:35:18.934346 mprotect(0x39ad18a000, 2097152, PROT_NONE) = 0
09:35:18.934528 mmap(0x39ad38a000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18a000) = 0x39ad38a000
09:35:18.934739 mmap(0x39ad390000, 14632, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x39ad390000
09:35:18.934928 close(3)                = 0
09:35:18.935128 open("/lib64/libdl.so.2", O_RDONLY) = 3
09:35:18.935483 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\r\300\2559\0\0\0@\0\0\0\0\0\0\0\260P\0\0\0\0\0\0\0\0\0\0@\0008\0\t\0@\0&\0%\0"..., 832) = 832
09:35:18.935671 fstat(3, {
   st_mode=S_IFREG|0755, st_size=23088, ...}) = 0
09:35:18.935874 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f874a99d000
09:35:18.936063 mmap(0x39adc00000, 2109696, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39adc00000
09:35:18.936284 mprotect(0x39adc02000, 2097152, PROT_NONE) = 0
09:35:18.936538 mmap(0x39ade02000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x39ade02000
09:35:18.936790 close(3)                = 0
09:35:18.937030 open("/lib64/libpthread.so.0", O_RDONLY) = 3
09:35:18.937304 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000^\200\2559\0\0\0@\0\0\0\0\0\0\0 2\2\0\0\0\0\0\0\0\0\0@\0008\0\t\0@\0*\0)\0"..., 832) = 832
09:35:18.937529 fstat(3, {
   st_mode=S_IFREG|0755, st_size=146592, ...}) = 0
09:35:18.937761 mmap(0x39ad800000, 2212848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39ad800000
09:35:18.938002 mprotect(0x39ad817000, 2097152, PROT_NONE) = 0
09:35:18.938233 mmap(0x39ada17000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x39ada17000
09:35:18.938527 mmap(0x39ada19000, 13296, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x39ada19000
09:35:18.938782 close(3)                = 0
09:35:18.939037 open("/lib64/libattr.so.1", O_RDONLY) = 3
09:35:18.939305 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\23\200\2579\0\0\0@\0\0\0\0\0\0\0 K\0\0\0\0\0\0\0\0\0\0@\0008\0\7\0@\0\36\0\35\0"..., 832) = 832
09:35:18.939537 fstat(3, {
   st_mode=S_IFREG|0755, st_size=21152, ...}) = 0
09:35:18.939760 mmap(0x39af800000, 2113888, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x39af800000
09:35:18.940002 mprotect(0x39af804000, 2093056, PROT_NONE) = 0
09:35:18.940225 mmap(0x39afa03000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x39afa03000
09:35:18.940467 close(3)                = 0
09:35:18.940672 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f874a99c000
09:35:18.940931 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f874a99a000
09:35:18.941144 arch_prctl(ARCH_SET_FS, 0x7f874a99a7a0) = 0
09:35:18.941463 mprotect(0x39aea1c000, 4096, PROT_READ) = 0
09:35:18.941706 mprotect(0x39ae606000, 4096, PROT_READ) = 0
09:35:18.941971 mprotect(0x39b7e06000, 4096, PROT_READ) = 0
09:35:18.942204 mprotect(0x39ad38a000, 16384, PROT_READ) = 0
09:35:18.942417 mprotect(0x39ade02000, 4096, PROT_READ) = 0
09:35:18.942635 mprotect(0x39ace20000, 4096, PROT_READ) = 0
09:35:18.942850 mprotect(0x39ada17000, 4096, PROT_READ) = 0
09:35:18.943080 mprotect(0x39afa03000, 4096, PROT_READ) = 0
09:35:18.943336 munmap(0x7f874a99f000, 41496) = 0
09:35:18.943602 set_tid_address(0x7f874a99aa70) = 20542
09:35:18.943791 set_robust_list(0x7f874a99aa80, 24) = 0
09:35:18.944033 futex(0x7ffc4edd7a8c, FUTEX_WAKE_PRIVATE, 1) = 0
09:35:18.944228 futex(0x7ffc4edd7a8c, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1, NULL, 7f874a99a7a0) = -1 EAGAIN (Resource temporarily unavailable)
09:35:18.944457 rt_sigaction(SIGRTMIN, {
   0x39ad805cb0, [], SA_RESTORER|SA_SIGINFO, 0x39ad80f7e0}, NULL, 8) = 0
09:35:18.944706 rt_sigaction(SIGRT_1, {
   0x39ad805d40, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x39ad80f7e0}, NULL, 8) = 0
09:35:18.944939 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
09:35:18.945172 getrlimit(RLIMIT_STACK, {
   rlim_cur=10240*1024, rlim_max=RLIM64_INFINITY}) = 0
09:35:18.945535 statfs("/selinux", {
   f_type="EXT2_SUPER_MAGIC", f_bsize=4096, f_blocks=10320720, f_bfree=3070821, f_bavail=2546559, f_files=2621440, f_ffree=2090835, f_fsid={
   387891684, 134857724}, f_namelen=255, f_frsize=4096}) = 0
09:35:18.945935 brk(0)                  = 0x2594000
09:35:18.946144 brk(0x25b5000)          = 0x25b5000
09:35:18.946415 open("/proc/filesystems", O_RDONLY) = 3
09:35:18.946742 fstat(3, {
   st_mode=S_IFREG|0444, st_size=0, ...}) = 0
09:35:18.946974 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f874a9a9000
09:35:18.947208 read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tbdev\nnodev\tproc\nnodev\tcgroup\nnode"..., 1024) = 310
09:35:18.947511 read(3, "", 1024)       = 0
09:35:18.947726 close(3)                = 0
09:35:18.947951 munmap(0x7f874a9a9000, 4096) = 0
09:35:18.948252 open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
09:35:18.948514 fstat(3, {
   st_mode=S_IFREG|0644, st_size=99174448, ...}) = 0
09:35:18.948713 mmap(NULL, 99174448, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f8744b05000
09:35:18.948965 close(3)                = 0
09:35:18.949257 ioctl(1, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {
   B38400 opost isig icanon echo ...}) = 0
09:35:18.949501 ioctl(1, TIOCGWINSZ, {
   ws_row=62, ws_col=204, ws_xpixel=1430, ws_ypixel=869}) = 0
09:35:18.949764 open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
09:35:18.950007 fcntl(3, F_GETFD)       = 0x1 (flags FD_CLOEXEC)
09:35:18.950241 getdents(3, /* 5 entries */, 32768) = 144
09:35:18.950497 getdents(3, /* 0 entries */, 32768) = 0
09:35:18.950696 close(3)                = 0
09:35:18.950969 fstat(1, {
   st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
09:35:18.951187 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f874a9a9000
09:35:18.951404 write(1, "demo-shell  demo-shell.c  strace-log\n", 37) = 37
09:35:18.951643 close(1)                = 0
09:35:18.951848 munmap(0x7f874a9a9000, 4096) = 0
09:35:18.952108 close(2)                = 0
09:35:18.952365 exit_group(0)           = ?
09:35:18.952833 +++ exited with 0 +++
[root@demo lab]#

训练并且享受你的刀锋战队吧。

参考

  1. The Design of the UNIX Operating System
  2. Modern Operating System 4th 中文版
  3. Linux内核交互图
相关文章
|
12月前
|
Ubuntu Linux Anolis
Linux系统禁用swap
本文介绍了在新版本Linux系统(如Ubuntu 20.04+、CentOS Stream、openEuler等)中禁用swap的两种方法。传统通过注释/etc/fstab中swap行的方式已失效,现需使用systemd管理swap.target服务或在/etc/fstab中添加noauto参数实现禁用。方法1通过屏蔽swap.target适用于新版系统,方法2通过修改fstab挂载选项更通用,兼容所有系统。
982 3
Linux系统禁用swap
|
12月前
|
安全 Linux Shell
四、Linux核心工具:Vim, 文件链接与SSH
要想在Linux世界里游刃有余,光会“走路”还不够,还得配上几样“高级装备”。首先是Vim编辑器,它像一把瑞士军刀,让你能在命令行里高效地修改文件。然后要懂“软硬链接”,软链接像个快捷方式,硬链接则是给文件起了个别名。最后,SSH是你的“传送门”,不仅能让你安全地远程登录服务器,还能用scp轻松传输文件,设置好密钥更能实现免-密登录,极大提升效率。
668 5
|
12月前
|
Linux
Linux系统修改网卡名为eth0、eth1
在Linux系统中,可通过修改GRUB配置和创建Udev规则或使用systemd链接文件,将网卡名改为`eth0`、`eth1`等传统命名方式,适用于多种发行版并支持多网卡配置。
1572 3
|
Ubuntu Linux 网络安全
Linux系统初始化脚本
一款支持Rocky、CentOS、Ubuntu、Debian、openEuler等主流Linux发行版的系统初始化Shell脚本,涵盖网络配置、主机名设置、镜像源更换、安全加固等多项功能,适配单/双网卡环境,支持UEFI引导,提供多版本下载与持续更新。
1054 3
Linux系统初始化脚本
|
12月前
|
Unix Linux 程序员
Linux文本搜索工具grep命令使用指南
以上就是对Linux环境下强大工具 `grep` 的基础到进阶功能介绍。它不仅能够执行简单文字查询任务还能够处理复杂文字处理任务,并且支持强大而灵活地正则表达规范来增加查询精度与效率。无论您是程序员、数据分析师还是系统管理员,在日常工作中熟练运用该命令都将极大提升您处理和分析数据效率。
895 16
|
12月前
|
安全 Linux iOS开发
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
442 0
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
|
12月前
|
安全 Linux Shell
Linux系统提权方式全面总结:从基础到高级攻防技术
本文全面总结Linux系统提权技术,涵盖权限体系、配置错误、漏洞利用、密码攻击等方法,帮助安全研究人员掌握攻防技术,提升系统防护能力。
1201 1
|
Linux 测试技术
Linux性能测试 strace命令
1  功能说明 strace 命令是一种强大的工具 ,  能够显示任何由用户空间程式发出的系统调用 .  strace 显示这些调用的参数并返回符号形式的值 .  strace 从内核接收信息 ,  而且无需以任何特别的方式来构建内核 .
1244 0
|
Linux
linux跟踪线程的方法:LWP和strace命令
摘要:在使用多线程程序时,有时会遇到程序功能异常的情况,而这种异常情况并不是每次都发生,很难模拟出来。这时就需要运用在程序运行时跟踪线程的手段,而linux系统的LWP和strace命令正是这种技术手段。
2179 0