本文介绍了将argv [0]设置为比当前分配的值更长的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用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]设置为比当前分配的值更长的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 18:02