打印pid与%d对%ld,linux [英] printing pid with %d vs %ld, linux

查看:649
本文介绍了打印pid与%d对%ld,linux的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将一系列 pid (即Linux进程ID)存储在 long 。我意识到 pid 不是 long ,但是我没有选择使用不同的变量类型。

I'm storing a series of pids (i.e. Linux process ids) in an array of longs. I realize that a pid is not a long, but I have no choice in terms of using a different variable type.

当我尝试使用 printf打印 pid 。如果我打印使用%ld pid long >,我得到错误的pids:

The issue I'm having occurs when I try and print the pid using printf. If I print the long that stores the pid using %ld, I get the wrong pids:

8435315771308 process_ancesto
8358006359962 bash
8353711392665 login
4294967297 init
0 swapper/0

但是,如果我使用%d (生成编译器警告),我得到正确的结果(即通过在终端中键入 ps 返回的结果):

However, if I print using %d (which generates a compiler warning), I get the correct result (i.e. the result returned by typing ps into the terminal):

1969 process_ancesto
1946 bash
1945 login
1 init
0 swapper/0

导致此行为的原因是什么? A pid - > long cast是一个扩展的转换,不应该引起任何问题。

What is causing this behaviour? A pid -> long cast is a widening conversion and shouldn't cause any problems.

这里是我用来做系统调用返回pids的程序: / p>

Here is the program I use to make the system call that returns the 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;
}

如果我替换%d %ld 它打印不正确的信息。

If I replace the %d with %ld it prints incorrect info.

这是从我的系统调用, pid

Here is the line from my system call where I record the pid:

if(copy_long_to_user(&info_array[num_filled_kernel].pid, &curr_task->pid)) {                
            return -EFAULT;
        }

info_array [num_filled_kernel] .pid

info_array[num_filled_kernel].pid is a long.

有两个问题:

推荐答案

copy_to_user 中,第二个参数是指向 pid_t 的指针,它出现, c $ c> int (32位)。所以你从一个32位变量复制64位;剩下的32位(高一半,因为x86是小端序)将填充任何内存中的下一个,如果你是幸运的。

In your copy_to_user, the second argument is a pointer to pid_t, it appears, which as you say is an int (32 bits). So you are copying 64 bits from a 32-bit variable; the remaining 32 bits (the high half, since x86 is little-endian) will be filled with whatever came next in memory, if you are lucky. (If you are unlucky you get a fault here.) Integer conversions aren't done when you access things via pointers.

安全地执行这个操作的最简单的方法是使用一个临时变量:

The simplest way to do this safely is to use a temporary variable:

long tmp = curr_task->pid; // sign-extension done here
copy_long_to_user(..., &tmp);

然后在用户空间代码中,使用%d 格式说明符打印显然是 long 的东西。这不会工作; printf 是一个可变函数,不知道它的参数应该具有的类型,因此不能适当地转换它们。如果您要通过,请使用%ld 格式说明符。

Then in your user space code, you are using the %d format specifier to print something that's apparently a long. This won't work; printf, being a variadic function, doesn't know the type that its arguments are expected to have, and so can't convert them appropriately. If you're going to pass a long, use the %ld format specifier.

这篇关于打印pid与%d对%ld,linux的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆