问题描述
我正在用C编写一个程序,该程序产生大量的进程,并且应该通过argv [0]报告它们的状态,因此在调用ps
时很容易看到正在发生的事情.
I am writing a program in C that spawns loads of processes and that should report their state via argv[0] so while calling ps
it's easy to see what's going on.
我知道最初argv [0]分配了某些内存,其中包含程序名称(在大多数情况下).
I am aware that initially argv[0] comes with certain memory allocated, that contains the program name (in most cases).
但是,我需要设置比包含我的程序名称的20个字节长得多的字符串.我的状态可以是80-100个字符.
I need however to set much longer string than 20 bytes that contain my program name. My status can be 80-100 characters long.
我进行了一些测试,如果将更长的字符串存入argv [0],它将为我工作",但我担心我将开始写入未拥有的内存,并导致段错误,这是不可接受的.
I made some tests and if I memcpy this longer string into argv[0] it "works for me" but I am afraid that I will start writing into unowned memory and cause segfault which is unacceptable.
如何安全地调整为argv [0]分配的内存大小?
How can I safely resize memory allocated for argv[0]?
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* generate_really_long_program_name() {
return strdup("here is something that generates really long program name\0");
}
int main (int argc, char *argv[])
{
printf("Current argv[0] length: %zu\n", strlen(argv[0]));
char* my_program_name = generate_really_long_program_name();
strncpy(argv[0], my_program_name, strlen(my_program_name)); // Can this segfault?
free(my_program_name);
printf("New argv[0] length: %zu\n", strlen(argv[0]));
return 0;
}
示例输出:
$ ./argv
Current argv[0] length: 6
New argv[0] length: 57
推荐答案
要在Linux下更改ps
中的名称显示,请使用 prctl
而不是更改argv[0]
(这是一个hack-该hack不适用于任何地方):
To change name display in ps
under Linux, use prctl
instead of changing argv[0]
(which is a hack - and this hack doesn't work on everywhere):
int s;
s = prctl(PR_SET_NAME,"myProcess\0",NULL,NULL,NULL);
执行此行后,查看ps
,您将看到"myProcess"而不是原始名称.
After this line execution, take a look at ps
, you will see "myProcess" instead of original name.
您可以自由地将任何想要的字符串传递给prctl
,而不必考虑argv[0]
的原始长度.但是,如果您的字符串超过16个字节(包括终止空字节),则会被截断:
You are free to pass any string you want to prctl
, regardless original length of argv[0]
. But if your string is more than 16 bytes (including terminating null byte, it will be truncated:
您对此有疑问:
For your question about this:
strncpy(argv[0], my_program_name, strlen(my_program_name)); // Can this segfault?
C99标准说:
,但是您不能增加argv[0]
的大小,因此,如果strlen(my_program_name)
大于argv[0]
的已分配内存,则会出现未定义的行为:缓冲区溢出,segfault或其他任何东西,因为它是UB
but you can't increase size of argv[0]
, so you will get an undefined behavior if strlen(my_program_name)
is greater than already allocated memory for argv[0]
: buffer overflow, segfault or anything else because it's UB
这篇关于将argv [0]设置为比当前分配的值更长的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!