Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用ptrace时mmap的返回值_C++_Linux_Return_Mmap_Ptrace - Fatal编程技术网

C++ 使用ptrace时mmap的返回值

C++ 使用ptrace时mmap的返回值,c++,linux,return,mmap,ptrace,C++,Linux,Return,Mmap,Ptrace,我在学习如何使用ptrace时遇到了一个奇怪的问题: 我写了一个程序: #include <cstdio> #include <sys/mman.h> #include <string.h> #include <errno.h> int main() { long x=(long)mmap(0,-235,2,34,-1,0); printf("Child: x=%ld (",x); for(int i=31;i>=0

我在学习如何使用ptrace时遇到了一个奇怪的问题:

我写了一个程序:

#include <cstdio>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>

int main()
{
    long x=(long)mmap(0,-235,2,34,-1,0);
    printf("Child: x=%ld (",x);
    for(int i=31;i>=0;i--) printf((x&(1<<i))?"1":"0");
    printf(")\n");
    printf("Child errno: %s\n",strerror(errno));
    return 0;
}
我和strace一起运行它:

execve("./nic.e", ["./nic.e"], [/* 35 vars */]) = 0
uname({sys="Linux", node="dom", ...})   = 0
brk(0)                                  = 0x9237000
brk(0x9237cd0)                          = 0x9237cd0
set_thread_area({entry_number:-1 -> 6, base_addr:0x9237830, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
brk(0x9258cd0)                          = 0x9258cd0
brk(0x9259000)                          = 0x9259000
mmap2(NULL, 4294967061, PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7798000
write(1, "Child: x=-1 (1111111111111111111"..., 47Child: x=-1 (11111111111111111111111111111111)
) = 47
write(1, "Child errno: Cannot allocate mem"..., 36Child errno: Cannot allocate memory
) = 36
exit_group(0)                           = ?
strace告诉我们,这个错误的mmap返回-1,错误为ENOMEM

直到现在一切都很好

这里是我的ptrace代码(我剪切了所有不需要的东西):


为什么mmap返回-12?我是否捕获的返回值不正确?

在32位x86 linux%eax上,包含返回值或错误时的否定错误值

参见例如,或

syscall返回值-12表示函数失败,errno应设置为12,至少在我的系统上与ENOMEM匹配

看来strace正在帮你翻译这篇文章。如果希望应用程序表现为strace,则应执行类似于中的测试和转换:


ENOMEM
在我的系统上是12,它与-12返回值匹配。Strace可能只是将其转换为正常的-1返回值,并将errno设置为您作为用户看到的ENOMEM(12)。不幸的是,我现在似乎找不到合适的参考资料。错过了编辑窗口:检查第3.3和3.4部分谢谢你的解释。我认为c函数只是进行系统调用,不做任何更改。这个链接真的很有用。目前它实际上是133,但我认为2048应该可以安全使用。@IgnacioVazquez Abrams:谢谢,已更改。请注意,系统调用
mmap
和C库
mmap()
的返回值/约定之间可能存在混淆,它获取系统调用的结果,并以某种方式对其进行解释,以向用户返回有意义的内容
ptrace
显示的是系统调用的结果,而不是C库调用的结果。
execve("./nic.e", ["./nic.e"], [/* 35 vars */]) = 0
uname({sys="Linux", node="dom", ...})   = 0
brk(0)                                  = 0x9237000
brk(0x9237cd0)                          = 0x9237cd0
set_thread_area({entry_number:-1 -> 6, base_addr:0x9237830, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
brk(0x9258cd0)                          = 0x9258cd0
brk(0x9259000)                          = 0x9259000
mmap2(NULL, 4294967061, PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7798000
write(1, "Child: x=-1 (1111111111111111111"..., 47Child: x=-1 (11111111111111111111111111111111)
) = 47
write(1, "Child errno: Cannot allocate mem"..., 36Child errno: Cannot allocate memory
) = 36
exit_group(0)                           = ?
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <sys/reg.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>

int main(int argc,char**argv)
{
    int pid=fork();
    if(!pid)
    {
        ptrace(PTRACE_TRACEME,0,NULL,NULL);
        execve("nic.e",NULL,NULL);
        exit(1);
    }

    while(true)
    {
        int status;
        waitpid(pid,&status,0);

        if(WIFEXITED(status)) return 0;

        int signal;

        if(WIFSTOPPED(status))
        {
            signal=WSTOPSIG(status);
        }

        if(WIFSIGNALED(status)) return 0;

        if(signal==SIGTRAP)
        {
            user_regs_struct regs;
            ptrace(PTRACE_GETREGS,pid,NULL,&regs);

            if(regs.orig_eax==__NR_mmap2)
            {
                static bool mmap_back=false;
                if(!mmap_back) mmap_back=true;
                else
                {
                    mmap_back=false;
                    long x=regs.eax;
                    printf("mmap return: %ld (",x);
                    for(int j=31;j>=0;j--) printf((x&(1<<j))?"1":"0");
                    printf(")\n");
                }
            }
        }
        ptrace(PTRACE_SYSCALL,pid,NULL,NULL);
    }
    return 0;
}
mmap return: -12 (11111111111111111111111111110100)
mmap return: -1216753664 (10110111011110011101000000000000)
Child: x=-1 (11111111111111111111111111111111)
Child errno: Cannot allocate memory
if ((unsigned long)(x) >= (unsigned long)(-2048)) {
    printf("syscall failed. errno = %ld\n", -(res));
}