【问题标题】:C - syscall - 64-bit - pointerC - 系统调用 - 64 位 - 指针
【发布时间】:2016-07-28 15:33:17
【问题描述】:

我使用的是 64 位 Linux x86。我需要使用syscall 函数执行mmap 系统调用。 mmap 系统调用号为 9:

printf("mmap-1: %lli\n", syscall(9,    0, 10, 3, 2 | 32, -1, 0));
printf("mmap-2: %lli\n", mmap(         0, 10, 3, 2 | 32, -1, 0));

但是,当我运行它时,syscall 函数给出了错误的结果。

mmap-1: 2236940288
mmap-2: 140503502090240

mmap-1: 3425849344
mmap-2: 140612065181696

mmap-1: 249544704
mmap-2: 139625341366272

mmap 工作得很好,但返回的“地址”syscall 导致Segmentation faultsyscall 的值似乎被转换为 32 位或其他东西。

我做错了什么?

【问题讨论】:

  • 据我在手册页上看到,syscall 返回一个int,而不是long long 或指针...?!?
  • 来自关于syscall() 的返回值The return value is defined by the system call being invoked. In general, a 0 return value indicates success. A -1 return value indicates an error, and an error code is stored in errno. 的手册页。您可能想查看herehere 了解更多信息。
  • @DevSolar 没错,我现在正在使用 gcc,但是,在另一个使用 Node.js gyp 编译器的项目中,我认为 syscall 返回了 64 位值,并且一切正常。无论如何,执行“64 位”系统调用的正确方法是什么?
  • 这个page 说系统调用返回long
  • 如果它返回long,那你为什么要打印%llilong的前缀是l

标签: c system-calls mmap


【解决方案1】:

在您的syscall() 中,不是为第一个参数addr 传递0 (NULL),而是传递一些您之前声明的指针。这样你就可以访问mmap映射的内存。 mmap函数声明:

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

【讨论】:

    【解决方案2】:

    找到问题的原因:我在运行gcc-std=c99 选项,删除它解决了问题:

    mmap-1: 139975263928320
    mmap-2: 139975263924224
    

    我猜,-std=99 将 syscall 定义为 int syscall(),没有它则为 long syscall()

    【讨论】:

    • 不,syscall 函数不是 C 函数。它是一个 POSIX 函数,所以它的参数和返回类型取决于 POSIX 标准,它不会随 C99 改变
    • @LưuVĩnhPhúc 我从 gcc 参数中删除了 -std=c99,现在它返回 64 位值
    • 正如我所说,使用错误的格式说明符是未定义的行为,任何事情都可能发生。 printf 是一个可变参数函数,对类型一无所知,因此要求用户使用正确的格式
    猜你喜欢
    • 2016-04-19
    • 2018-06-06
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2016-08-01
    • 2012-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多