Ada*_*dam 1 c linux printf casting
我在一个pids数组中存储了一系列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 次 |
| 最近记录: |