2012-04-28 37 views

Trả lời

12

Trong tiêu chuẩn C và glibc, bạn đã argv [0]:

int main (int argc, char *argv[]) 

phần tử đầu tiên của argv mảng là tên chương trình.

Tuy nhiên, không nhất thiết phải tự mình xác định chính xác nơi thực thi. Đối số thực sự được thiết lập bởi chương trình chạy chương trình của bạn - có thể là trình bao hoặc trình quản lý cửa sổ - và chúng không hữu ích lắm. Nếu chương trình của bạn là trong đường dẫn và bạn chạy chương trình đơn giản với

your_program

tại một vỏ bash, sau đó "your_program" là tất cả các bạn sẽ nhận được trong argv [0].

Đối với đường dẫn thực thi đầy đủ, linux có /proc filesystem. Dưới /proc mỗi quy trình đang chạy có "thư mục" riêng, được đặt tên theo id tiến trình của nó. Quá trình chạy cũng có thể thấy cây con riêng của mình dưới /proc/self. Một trong các tệp mà mỗi tiến trình nhận được là /proc/[pid]/exe, là một liên kết tượng trưng cho quá trình thực thi thực tế mà tiến trình đang chạy.

Vì vậy, bạn có thể nhận được đường dẫn thực tế đầy đủ thực thi như thế này:

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

int main(void) { 
    char exe[1024]; 
    int ret; 

    ret = readlink("/proc/self/exe",exe,sizeof(exe)-1); 
    if(ret ==-1) { 
     fprintf(stderr,"ERRORRRRR\n"); 
     exit(1); 
    } 
    exe[ret] = 0; 
    printf("I am %s\n",exe); 
} 

Bạn cũng có thể vượt qua /proc/[pid]/exe trực tiếp đến addr2line().

+1

Tuyệt vời! điều này làm việc hoàn hảo – lurscher

+0

Trong trường hợp này, việc sử dụng '/ proc/self/exe' dễ dàng hơn để không cần gọi' getpid() '. – Diego

5

Bạn có thể truy cập vào argv [0] mà không có một tham chiếu đến biến thực tế, bằng cách sử dụng một con trỏ lưu trong glibc: https://github.com/rbdixon/glibc/blob/master/misc/init-misc.c

Ví dụ sử dụng:

extern const char *__progname; 

int print_progname() 
{ 
    return puts(__progname); 
} 

argv [0] không nhất thiết phản ánh tên được sử dụng để gọi chương trình. Xem man 2 execveman 7 environ để biết thêm thông tin.

Các vấn đề liên quan