我正在用C语言编写一个程序来生成大量进程,并且应该通过argv [0]报告它们的状态,所以在调用ps
很容易看出发生了什么。
我知道最初argv [0]带有一定的内存分配,包含程序名称(在大多数情况下)。
但是,我需要设置比包含程序名称的20个字节更长的字符串。 我的状态可以是80-100个字符。
我做了一些测试,如果我把这个更长的字符串记忆到argv [0]中它“对我有效”但我担心我会开始写入无主内存并导致段错误,这是不可接受的。
如何安全地调整为argv [0]分配的内存?
示例代码:
#include #include #include char* generate_really_long_program_name() { return strdup("here is something that generates really long program name "); } int main (int argc, char *argv[]) { printf("Current argv[0] length: %zun", 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: %zun", strlen(argv[0])); return 0; }
样本输出:
$ ./argv Current argv[0] length: 6 New argv[0] length: 57
要在Linux下更改ps
名称显示,请使用prctl
而不是更改argv[0]
(这是一个hack – 而且这个hack在任何地方都不起作用):
int s; s = prctl(PR_SET_NAME,"myProcess ",NULL,NULL,NULL);
执行此行后,看看ps
,您将看到“myProcess”而不是原始名称。
无论原始长度为argv[0]
,您都可以自由传递任何想要传递的字符串。 但是如果你的字符串超过16个字节(包括终止空字节,它将被截断:
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是调用线程的名称。
对于你的问题:
strncpy(argv[0], my_program_name, strlen(my_program_name)); // Can this segfault?
C99标准说:
参数
argc
和argv
以及argv数组指向的字符串应该可由程序修改,并在程序启动和程序终止之间保留它们最后存储的值。
但你不能增加argv[0]
大小,所以如果strlen(my_program_name)
大于argv[0]
已经分配的内存,你将得到一个未定义的行为:缓冲区溢出,段错误或其他任何因为它是UB
以上就是c/c++开发分享将argv 设置为比当前分配的值更长的值相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/519726.html