Ada*_*dam 1 c linux printf casting
我在一个pid
s数组中存储了一系列s(即Linux进程ID)long
.我意识到a pid
不是a long
,但我在使用不同的变量类型方面别无选择.
当我尝试打印pid
使用时,我遇到了这个问题printf
.如果我打印long
存储pid
使用的%ld
,我得到错误的pids:
8435315771308 process_ancesto
8358006359962 bash
8353711392665 login
4294967297 init
0 swapper/0
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用打印%d
(生成编译器警告),我会得到正确的结果(即通过键入ps
终端返回的结果):
1969 process_ancesto
1946 bash
1945 login
1 init
0 swapper/0
Run Code Online (Sandbox Code Playgroud)
是什么导致了这种行为?pid - > long cast是一个扩大的转换,不应该导致任何问题.
这是我用来进行系统调用的程序,它返回pids:
int main(int argc, char *argv[])
{
struct process_info arr[10];
long n=0;
int result = syscall(_CS300_PROCESS_ANCESTORS_, arr,10,&n);
assert(result==0);
for(int i=0;i<n;i++) {
printf("%d %s\n",arr[i].pid,arr[i].name);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我更换%d
用%ld
它打印不正确的信息.
这是我系统调用的行,我记录了pid
:
if(copy_long_to_user(&info_array[num_filled_kernel].pid, &curr_task->pid)) {
return -EFAULT;
}
Run Code Online (Sandbox Code Playgroud)
info_array[num_filled_kernel].pid
很久了.
两个问题:
在你的copy_to_user
,第二个参数是一个指针pid_t
,它出现,如你所说是一个int
(32位).所以你从32位变量复制64位; 如果幸运的话,其余的32位(高半部分,因为x86是小端)将填充内存中的下一个内容.(如果你运气不好,你会在这里遇到错误.)当你通过指针访问事物时,不会进行整数转换.
安全地执行此操作的最简单方法是使用临时变量:
long tmp = curr_task->pid; // sign-extension done here
copy_long_to_user(..., &tmp);
Run Code Online (Sandbox Code Playgroud)
然后在您的用户空间代码中,您使用%d
格式说明符来打印显然是的东西long
.这不起作用; printf
作为一个可变函数,它不知道它的参数预期具有的类型,因此不能适当地转换它们.如果您要传递a long
,请使用%ld
格式说明符.
归档时间: |
|
查看次数: |
676 次 |
最近记录: |