Tôi tự hỏi nếu có một hàm glibc mà tôi có thể sử dụng từ gcc/g ++ sẽ truy xuất tệp thực thi hiện tại.chức năng glibc để lấy tên thực thi hiện tại?
Mục đích của việc này là để cung cấp các luận cứ -e để addr2line
như trong this answer
Tôi tự hỏi nếu có một hàm glibc mà tôi có thể sử dụng từ gcc/g ++ sẽ truy xuất tệp thực thi hiện tại.chức năng glibc để lấy tên thực thi hiện tại?
Mục đích của việc này là để cung cấp các luận cứ -e để addr2line
như trong this answer
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()
.
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 execve và man 7 environ để biết thêm thông tin.
Bạn có thể lấy nó từ argv [0] – BlackBear
Là argv [0] không phải những gì bạn muốn, vì một lý do nào đó? – thb