将argv [0]设置为比当前分配的值更长的值 [英] Setting argv[0] to longer value than currently allocated

查看:111
本文介绍了将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中的名称显示,请使用

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:

PR_SET_NAME(自Linux 2.6.9起)
使用 (char *)arg2指向的位置.名称最多 16个字节长,包括终止的空字节. (如果 字符串的长度,包括终止的空字节, 超过16个字节,该字符串将被静默截断.)这是 可以通过pthread_setname_np(3)设置的相同属性 并使用pthread_getname_np(3)进行检索.该属性是 同样可以通过/proc/self/task/[tid]/comm访问,其中tid 是调用线程的名称.

PR_SET_NAME (since Linux 2.6.9)
Set the name of the calling thread, using the value in the location pointed to by (char *) arg2. The name can be up to 16 bytes long, including the terminating null byte. (If the length of the string, including the terminating null byte, exceeds 16 bytes, the string is silently truncated.) This is the same attribute that can be set via pthread_setname_np(3) and retrieved using pthread_getname_np(3). The attribute is likewise accessible via /proc/self/task/[tid]/comm, where tid is the name of the calling thread.


您对此有疑问:


For your question about this:

strncpy(argv[0], my_program_name, strlen(my_program_name)); // Can this segfault?

C99标准说:

程序必须可以修改参数argcargv以及argv数组所指向的字符串,并在程序启动和程序终止之间保留其最后存储的值.

The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆