2

So I have this task of changing the process name during runtime in C, and I've stumbled upon this: http://www.uofr.net/~greg/processname.html

Now before anything else, I am aware of the dangers of altering argv[0] (but have a long way to go about Linux and UNIX stuffs) so please don't lecture about it, I just want to know why it isn't working on Ubuntu.

Here is the test source I've used:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main(int argc, char *argv[]) {

    int argv0size = strlen(argv[0]);
    int onetwothree = 1;
    char* abc = (char *) malloc(sizeof(char) * (17 + 1));
    sprintf(abc,"ApplicationName%.3d",onetwothree); 
    strncpy(argv[0], abc ,argv0size);     
    getchar(); 
}

I've tested it on Mac OS X and Ubuntu only, and it's working on Mac OS X. I don't know why it's not working on Ubuntu. What could be the possible reasons for it not working?

I'm using gcc as compiler.

IBG
  • 465
  • 12
  • 34
  • 4
    what do you mean "not working"? – Aniket Inge Apr 03 '13 at 03:04
  • What are you passing to the program as argv[0] (ie, the name)? Print it out before changing it. I should mention that this is one of those situations where `strncpy` is dangerous (doesn't append NULL if not enough room). – paxdiablo Apr 03 '13 at 03:09
  • 1
    I don't think the "dangers" of modifying argv[0] are as bad as you think they are. According to the standard, C99 §5.1.2.2.1, "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." There is no distinction separating `argv[0]` from the others. Regardless, have you tried storing the pointer `abc` in argv[0] directly rather than trying to overwrite the data it points to? Just curious. – WhozCraig Apr 03 '13 at 03:15
  • 2
    "What could be the possible reasons for it not working?" -- Um, maybe Ubuntu doesn't use the that particular string instance as the process name. – Jim Balter Apr 03 '13 at 03:22
  • @Aniket I mean the process name is not changing. – IBG Apr 03 '13 at 04:13
  • @WhozCraig I did try. Same effect. I'm inclined to think that the answer below is correct in the statement that "Ubuntu is required to use that modification in it's process list." – IBG Apr 03 '13 at 04:15
  • @IBG I tend to agree with that assessment to. The standard only states the changes are process-wide, not process-hierarchy deep. – WhozCraig Apr 03 '13 at 04:28

2 Answers2

3

So I have this task of changing the process name during runtime in C, and I've stumbled upon this: http://www.uofr.net/~greg/processname.html

I would suggest that the reference you used wasn't written by an expert in OSes or C. Perhaps it works on some OSes, but it's not required to work that way in C.

Now before anything else, I am aware of the dangers of altering argv[0] (but have a long way to go about Linux and UNIX stuffs) so please don't lecture about it, I just want to know why it isn't working on Ubuntu.

As WhozCraig said in his comment, you're certainly allowed to modify the argv array, as well as the arrays that it points to. That doesn't mean Ubuntu is required to use that modification in its process list.

I've tested it on Mac OS X and Ubuntu only, and it's working on Mac OS X. I don't know why it's not working on Ubuntu. What could be the possible reasons for it not working?

If you're looking for a rationale, think of the potential for abuse. If your own copy of argv[0] were used in the process list, trojans such as kaiten would be able to forge their process name as they used to, to make them more difficult to detect and remove.

autistic
  • 1
  • 3
  • 35
  • 80
  • "That doesn't mean Ubuntu is required to use that modification in it's process list." Thanks for this thought. – IBG Apr 03 '13 at 04:17
  • 1
    So is `argv[0]` a modifiable lvalue? :-P – Mysticial Apr 03 '13 at 04:41
  • @Mysticial That guarantee is valid in this circumstance, yes. If you change the scope of the declaration, then that guarantee might become invalid. – autistic Apr 03 '13 at 05:01
  • 1
    Ah ok. I figured I'd get an answer if I asked a modifiable lvalue about whether or not something was a modifiable lvalue. :) – Mysticial Apr 03 '13 at 05:03
  • 1
    @Mysticial That raises an interesting challenge: Write a function that accepts an argument specifying an lvalue, and returns information regarding that lvalue, such as the storage duration of the lvalue and whether or not the lvalue is modifiable. Use whichever type and representation you like for the return value and any arguments. – autistic Apr 03 '13 at 05:13
  • btw, we're discussing your "challenge" in [chat right now](http://chat.stackoverflow.com/transcript/message/8630665#8630665). – Mysticial Apr 03 '13 at 05:24
  • Is it ok to accept @sree 's answer? His answer is working indeed, but in context my question just asks why mine's not, and you answered first. – IBG Apr 03 '13 at 06:36
  • 1
    @IBG I focused on answering only the questions asked, where your favourite answer also addresses questions you didn't think of. I won't hold it against you... after all, your favourite answer *is* your choice! – autistic Apr 03 '13 at 06:54
  • It's a conflicting emotion, but anyways you have my upvote and my gratitude. – IBG Apr 03 '13 at 07:36
  • 1
    @IBG I'm happy to help. Don't let it get at you, really... I'm not doing it for the number; The number is just an added bonus indicator of how awesome I am! ;) – autistic Apr 03 '13 at 09:21
2

Unfortunately, there's no guarantee in C that argv[0] is actually the process name. In Unix/Linux, it can be any arbitrary value that the parent process chooses to use (see 'execv/execve'). Which means its doesn't necessarily map to the process name although it may based on implementation.

For Ubuntu (and probably MacOS?) the following should be more universal:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __linux__
#include <sys/prctl.h>
#endif

void main(int argc, char *argv[]) {

  int argv0size = strlen(argv[0]);
  int onetwothree = 1;
  char* abc = (char *) malloc(sizeof(char) * (17 + 1));
  sprintf(abc,"ApplicationName%.3d",argv0size); 
  #ifdef __linux__
    prctl(PR_SET_NAME, abc, 0, 0, 0);
  #else
    strncpy(argv[0], abc ,argv0size);     
  #endif
  getchar(); 
}

EDIT: removed actual application name.
EDIT_2: prctl not available on OS X

sree
  • 183
  • 1
  • 5
  • There is indeed no guarantee that `argv[0]` will be the "process name" verbatim. Rather, the standard, C99 §5.1.2.2.1, specifies "If the value of `argc` is greater than zero, the string pointed to by `argv[0]` represents the *program name*; `argv[0][0]` shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters" [`prctl()`](http://man7.org/linux/man-pages/man2/prctl.2.html) is Linux-specific. It isn't available on Mac OS X ttbomk. – WhozCraig Apr 03 '13 at 04:33
  • Whoops - indeed. Not available on OS X. Looks like #ifdef worthy, unfortunately... though even there, I would not recommend argv[0] .... see http://stackoverflow.com/questions/4217947/setting-process-name-on-mac-os-x-at-runtime – sree Apr 03 '13 at 04:41
  • @modifiable lvalue - I was trying to minimally modify example source to solve the problem. But yes, no need for int cast (removed), and agree on style. – sree Apr 03 '13 at 04:51
  • @modifiable lvalue - and yes, did test --- only cast because prctl man page indicated I should (http://man7.org/linux/man-pages/man2/prctl.2.html) --- but compiles without warning even if I don't --- go figure :) – sree Apr 03 '13 at 04:52
  • @modifiable lvalue - apparently not. Just tried. No warning. Works as advertised. – sree Apr 03 '13 at 04:54
  • Why am I not seeing @modifiable lvalue 's comments? – IBG Apr 03 '13 at 06:29
  • About prctl, indeed it is not present in Mac OS X, but what I really need is an applicable one for Ubuntu. Thanks for going the distance and providing me with a better alternative. – IBG Apr 03 '13 at 07:40
  • Sorry got stuck with some ordeals recently so it took me long enough to ask this. Somehow this is not working on Eclipse CDT, but it works when simply compiled with gcc. I want to know if there's some special sauce I need to make it work with Eclipse? – IBG May 02 '13 at 05:58