【问题标题】:strace/ltrace outputs inconsistent infostrace/ltrace 输出不一致的信息
【发布时间】:2011-09-21 04:24:03
【问题描述】:

strace pwd:

getcwd("/root"..., 4096)                = 6

ltrace pwd:

getcwd(NULL, 0)                                     = "/root"

为什么ltrace中的第一个参数是NULL

似乎 strace/ltrace 都使用 ptrace 系统调用,但为什么它们得到不同的信息?

【问题讨论】:

    标签: strace ptrace ltrace


    【解决方案1】:

    ltrace 显示库调用。在这种情况下,它显示了源代码正在调用的来自libc 的函数。

    如果你看到pwd的源码,你会看到(coreutils-8.13,文件lib/xgetcwd.c):

    char *cwd = getcwd (NULL, 0);
    

    所以,ltrace 的输出是正确的:pwd 执行 getcwd(NULL, 0)。根据Linux手册页getcwd(3)

    如果 buf 为 NULL,getcwd() 会使用 malloc(3) 动态分配缓冲区。

    但是,系统调用getcwd(2) 总是需要一个不同于 NULL 的第一个参数,以便在那里复制路径名。您可以在 libc 源代码中看到这是如何完成的(例如 libc-3.13,文件 sysdeps/unix/sysv/linux/getcwd.c)。

    库调用getcwd(NULL, 0) 执行系统调用getcwd(path, alloc_size),其中path 是先前malloc() 的结果,alloc_size 是页面大小(4096)。

    为了确认这一点,如果你运行ltrace -S pwd,你会看到库调用和系统调用:你会看到类似:

    getcwd(NULL, 0 <unfinished ...>
    SYS_getcwd("/root", 4096)                        = 6
    <... getcwd resumed> )                           = "/root"
    

    【讨论】:

      【解决方案2】:

      对,他们都使用ptrace,而且他们得到的信息也不同。这是因为他们使用 ptrace 的方式不同。

      如果您查看ptrace man page,您会发现存在多个“请求”值,它们决定了 ptrace 的行为。

      更具体地说,如果您之前使用ptrace 设置选项PTRACE_O_TRACESYSGOOD,您可以区分导致系统调用的陷阱和不导致系统调用的陷阱。

      【讨论】:

        【解决方案3】:

        因为系统调用和库调用不同。阅读 getcwd 函数的手册页,您会发现它具有以下原型:

        long getcwd(char *buf, unsigned long size);
        

        【讨论】:

        • @zvrba,你为什么认为这回答了我的问题?
        • 因为手册页还解释了传递 NULL 是一个 linux 扩展。它也可能是 ltrace 中的一个错误。不看代码不可能知道。
        • ptrace() 对参数一无所知。函数/系统调用参数以及它们的解释方式被硬编码到 strace 和 ltrace 中。
        • @zvrba ,使 strace/ltrace 具有不同功能的最重要的代码控制位是什么?
        • 我不明白你在问什么。哪个功能? strace 挂钩系统调用机制,ltrace 修改动态库函数的入口点。
        猜你喜欢
        • 2014-10-31
        • 1970-01-01
        • 1970-01-01
        • 2017-08-30
        • 2011-08-16
        • 2023-03-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多