Linux内核系统调用返回-1而不是{-1,-256}

Linux内核系统调用返回-1而不是{-1,-256},第1张

概述我是一个内核新手,面临着一个奇怪的问题.我编写了一个概念验证计算器系统调用,虽然它适用于大多数计算,但当SUBTRACTION结果介于-1到-256之间时它返回-1.如果有人可以对可能发生的事情有所了解,那就会很感激.下面是系统调用代码. SYSCALL_DEFINE3(calc, int, a, int, b , char, op) { int res_int; switch(op) 我是一个内核新手,面临着一个奇怪的问题.我编写了一个概念验证计算器系统调用,虽然它适用于大多数计算,但当SUBTRACTION结果介于-1到-256之间时它返回-1.如果有人可以对可能发生的事情有所了解,那就会很感激.下面是系统调用代码. @H_419_7@

@H_419_7@

SYSCALL_define3(calc,int,a,b,char,op) {  int res_int;  switch(op) {    case '+': res_int = a + b;              break;    case '-': res_int = a - b;              break;    case '*': res_int = a * b;              break;    case '/': res_int = (a*1000) / b;              break;  }             printk(KERN_INFO "KERNEL CALC RESulT : %d %c %d = %ld",op,res_int);  return res_int;}
@H_419_7@编辑:
内核版本:AndroID linux Kernel 3.10.xxx.
平台:Nexus7 ARM EABI.
我不明白的是它失败的原因. errno完全没用,因为它将-res_int设置为errno.另外,我不明白为什么只有当res_int为{-1,-256}时才会失败.

@H_419_7@a = 1200,b = 1300 op =’ – ‘=> res_int = -100是printk打印-100的示例,但在我的用户空间应用程序中,我收到-1.

@H_419_7@看起来当res_int为{-1,-256}时,errno被设置为-res_int.

@H_419_7@

root@androID:/data/local # ./calc                                              Please enter request in 'num1 oper num2' format: 2.45 - 2.2returned from syscall with res_int = 250errno = 22,strerror(errno) = InvalID argumentCalculator result = 0.250000root@androID:/data/local # ./calc                                              Please enter request in 'num1 oper num2' format: 2.2 - 2.45returned from syscall with res_int = -1errno = 250,strerror(errno) = UnkNown error 250Calculator result = -0.001000root@androID:/data/local #
解决方法 你没有提到你的内核版本和平台但是fwiw,从内核的角度来看,系统调用通常在成功时返回零,在错误时返回负数.通常,这是内核人员和应用程序开发人员之间的ABI约定,因此代码可以相互理解. @H_419_7@

@H_419_7@但是用户程序总是使用C库作为包装来进行系统调用,而C API应该符合API标准.也就是说,C库将检查内核空间的返回值,并根据该值设置errno. (注意,errno在用户空间中,而内核不知道它.)
比方说,如果syscall foo(),从用户的视图,在失败时返回-1并且应该设置errno以指示错误(ERR1表示失败1,ERR2表示失败2等),内核系统调用实现将返回-ERR1或-ERR2因此,C库将检查返回值是否为零,如果它为负,它将返回-1给用户,并将errno设置为ERR1 / ERR2.
希望这可以帮助.

@H_419_7@更新:我检查了glibc的x86_64代码,这可能有助于理解这一点:

@H_419_7@

.textENTRY (syscall)        movq %rdi,%rax         /* Syscall number -> rax.  */        movq %rsi,%rdi         /* shift arg1 - arg5.  */        movq %rdx,%rsi        movq %rcx,%rdx        movq %r8,%r10        movq %r9,%r8        movq 8(%rsp),%r9        /* arg6 is on the stack.  */        syscall                 /* Do the system call.  */        cmpq $-4095,%rax       /* Check %rax for error.  */        jae SYSCALL_ERROR_LABEL /* Jump to error handler if error.  */L(pseudo_end):        ret                     /* Return to caller.  */PSEUDO_END (syscall)file: "sysdeps/unix/sysv/linux/x86_64/syscall.S"
@H_419_7@linus说他将确保no syscall返回-1 .. -4095中的值作为有效结果,因此我们可以使用-4095进行保存测试.

@H_419_7@更新:所以我猜你的c库转换了返回值.您的平台ABI可能会定义syscall在失败时返回{-1,-256},因此C包装器在这种情况下将返回值设置为-1并相应地设置errno.

总结

以上是内存溢出为你收集整理的Linux内核系统调用返回-1而不是{-1,-256}全部内容,希望文章能够帮你解决Linux内核系统调用返回-1而不是{-1,-256}所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/1022061.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-23
下一篇2022-05-23

发表评论

登录后才能评论

评论列表(0条)

    保存