LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   problem on /proc/self/exe and /proc/num/exe (https://www.linuxquestions.org/questions/programming-9/problem-on-proc-self-exe-and-proc-num-exe-478707/)

snowing 08-30-2006 04:27 AM

problem on /proc/self/exe and /proc/num/exe
 
In my project, I encountered a strange problem. As you know readlink(2) can be used to get the real running program by /proc/self/exe. For example:

on RHELU4 and RH9
test.c:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
char elf_file[65536];
pid_t pid;
char string[100];

pid = getpid();
printf("pid is %ld\n", pid);

sprintf(string, "/proc/%ld/exe", pid);
printf("string is %s\n", string);
sleep(20);
if (readlink(string, elf_file, 65536) == -1) {
perror("readlink");
return -1;
}
printf("real file is %s\n", elf_file);
}
compiled by "gcc test.c -o test -static". On ia64, x86_64 and i386, it's all OK. But if I run test as a ld, compiled with "gcc -Wl,--dynamic-linker test hello.c -o hello". It will fail on i386 and x86_64, but OK on ia64.
[root@hpc-rm ld]# ./hello
pid is 22226
string is /proc/22226/exe
readlink: No such file or directory
[root@hpc-rm ld]# ./test
pid is 22239
string is /proc/22239/exe
real file is /home/baiwd/ld/test
And on i386 and x86_64, when I "ll /proc/pid[num]/", there is /proc/pid/exe, but when I "ll /proc/pid[num]/exe", it reports "No such file or directory". Could you please tell me why? Thank you very much

randyding 08-30-2006 08:12 PM

Try using code tags around you source in the posts, makes it much easier to read.

readlink() does not place a null terminator on the end, you have to do that yourself using the return code as the index, after range checking it of course. See the man 2 readlink.

snowing 08-30-2006 08:30 PM

Thank you. But I am afraid that maybe it's not caused by readlink(2). In fact the "/proc/pidnumber/exe" does not exist, because when using command "ll /proc/pidnumber/exe", it reports "No such file or directory" too. So readlink failed.

randyding 08-30-2006 09:20 PM

Your program works for me after I fixed the readlink() problem.
I don't know what error you are seeing.
Code:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    char elf_file[65536];
    pid_t pid;
    char string[100];
    int res;


    pid=getpid();
    printf("pid is %d\n", pid);
    snprintf(string,sizeof(string),"/proc/%d/exe",pid);
    printf("string is %s\n", string);
    sleep(20);
    res=readlink(string,elf_file,sizeof(elf_file));
    if (res<=0 || res>=sizeof(elf_file)) {
        perror("readlink");
        return 1;
    }
    elf_file[res]='\0';
    printf("real file is %s\n",elf_file);
    return 0;
}


snowing 08-30-2006 10:04 PM

if I run the program test directly, it's all right, every thing is OK. But I want to use test as a faked linker and I want to figure out which program is running in this faked ld. But the /proc/<pid>/exe does not exist.

Quote:

[baiwd@hpc-rm ld]$ gcc -Wl,--dynamic-linker test hello.c -o hello
[baiwd@hpc-rm ld]$ cat hello.c
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
[baiwd@hpc-rm ld]$ ./hello
pid is 19738
string is /proc/19738/exe
readlink: No such file or directory
[root@hpc-rm ld]# ll /proc/19738/exe
ls: cannot read symbolic link /proc/19738/exe: No such file or directory
lrwxrwxrwx 1 baiwd baiwd 0 Aug 31 11:01 /proc/19738/exe

randyding 08-30-2006 11:09 PM

Hmm, sorry, the ld man page says this about --dynamic-linker
Code:

The default dynamic linker is normally correct;
don't use this unless you know what you are doing.

Since I never heard of this option, I probably don't know what I'm doing.
Maybe there's someone else that can assist you.

snowing 08-31-2006 01:17 AM

Thank you for your sparing time. Now another nice person give me the answer:
Quote:

The problem is that your "test" ld is linked to load at the same
address as hello:

$ objdump -p ./hello | grep LOAD | head -1
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
$ objdump -p ./test | grep LOAD | head -1
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12


You have to get your "test ld" out of the way by linking it at a
different address (using a linker script), or get your "hello"
executable out of the way by building it as a position-independent:


$ gcc -g junk.c -o test -static &&
gcc junk.c -Wl,--dynamic-linker=./test &&
./a.out
pid is 16060
string is /proc/16060/exe
readlink: No such file or directory


$ gcc -fPIC -pie junk.c -Wl,--dynamic-linker=./test &&
./a.out
pid is 16066
string is /proc/16066/exe
real file is /home/paul/a.out


All times are GMT -5. The time now is 02:40 PM.