Linux内核系统调用返回-1而不是{-1,-256}
我是一个内核新手,面临着一个奇怪的问题.我编写了一个概念验证计算器系统调用,虽然它适用于大多数计算,但当SUBTRACTION结果介于-1到-256之间时它返回-1.如果有人可以对可能发生的事情有所了解,那就会很感激.下面是系统调用代码.
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; } 编辑: a = 1200,b = 1300 op =’ – ‘=> res_int = -100是printk打印-100的示例,但在我的用户空间应用程序中,我收到-1. 看起来当res_int为{-1,-256}时,errno被设置为-res_int. root@android:/data/local # ./calc Please enter request in 'num1 oper num2' format: 2.45 - 2.2 returned from syscall with res_int = 250 errno = 22,strerror(errno) = Invalid argument Calculator result = 0.250000 root@android:/data/local # ./calc Please enter request in 'num1 oper num2' format: 2.2 - 2.45 returned from syscall with res_int = -1 errno = 250,strerror(errno) = Unknown error 250 Calculator result = -0.001000 root@android:/data/local # 解决方法
你没有提到你的内核版本和平台但是fwiw,从内核的角度来看,系统调用通常在成功时返回零,在错误时返回负数.通常,这是内核人员和应用程序开发人员之间的ABI约定,因此代码可以相互理解.
但是用户程序总是使用C库作为包装来进行系统调用,而C API应该符合API标准.也就是说,C库将检查内核空间的返回值,并根据该值设置errno. (注意,errno在用户空间中,而内核不知道它.) 更新:我检查了glibc的x86_64代码,这可能有助于理解这一点: .text ENTRY (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" Linus说他将确保no syscall返回-1 .. -4095中的值作为有效结果,因此我们可以使用-4095进行保存测试. 更新:所以我猜你的c库转换了返回值.您的平台ABI可能会定义syscall在失败时返回{-1,-256},因此C包装器在这种情况下将返回值设置为-1并相应地设置errno. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |