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

查看:21
本文介绍了将 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 不适用于所有地方):

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)大于已经为<分配的内存,你会得到一个未定义的行为code>argv[0]:缓冲区溢出、段错误或其他任何原因,因为它是 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天全站免登陆