Définition de argv sur une valeur plus longue que celle actuellement atsortingbuée

J’écris un programme en C qui génère des charges de processus et qui devrait signaler leur état via argv [0]. Ainsi, lorsque vous appelez ps il est facile de voir ce qui se passe.

Je suis conscient que initialement argv [0] est livré avec une certaine mémoire allouée, qui contient le nom du programme (dans la plupart des cas).

J’ai cependant besoin de définir une chaîne beaucoup plus longue que 20 octets contenant mon nom de programme. Mon statut peut contenir entre 80 et 100 caractères.

J’ai fait quelques tests et si je me souviens de cette chaîne plus longue dans argv [0] cela “fonctionne pour moi” mais j’ai peur de commencer à écrire dans une mémoire non possédée et à provoquer un segfault inacceptable.

Comment redimensionner en toute sécurité la mémoire allouée pour argv [0]?

Exemple de code:

 #include  #include  #include  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; } 

Exemple de sortie:

 $ ./argv Current argv[0] length: 6 New argv[0] length: 57 

Pour changer l’affichage du nom dans ps sous Linux, utilisez prctl au lieu de changer argv[0] (ce qui est un hack – et ce hack ne marche pas partout):

 int s; s = prctl(PR_SET_NAME,"myProcess\0",NULL,NULL,NULL); 

Après cette ligne, jetez un coup d’œil à ps , vous verrez “myProcess” au lieu du nom d’origine.

Vous êtes libre de passer toute chaîne que vous voulez programmer, quelle que soit la longueur d’origine de argv[0] . Mais si votre chaîne compte plus de 16 octets (y compris l’octet nul de terminaison, elle sera tronquée:

PR_SET_NAME (depuis Linux 2.6.9)
Définissez le nom du thread appelant, en utilisant la valeur de l’emplacement indiqué par (char *) arg2. Le nom peut avoir une longueur maximale de 16 octets, y compris l’octet nul final. (Si la longueur de la chaîne, y compris l’octet nul final, dépasse 16 octets, elle est automatiquement tronquée.) Il s’agit du même atsortingbut que celui que vous pouvez définir via pthread_setname_np (3) et récupéré à l’aide de pthread_getname_np (3). L’atsortingbut est également accessible via / proc / self / task / [tid] / comm, où tid est le nom du thread appelant.


Pour votre question à ce sujet:

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

La norme C99 dit:

Les parameters argc et argv et les chaînes pointées par le tableau argv doivent être modifiables par le programme et conserver leurs dernières valeurs stockées entre le démarrage et la fin du programme.

mais vous ne pouvez pas augmenter la taille de argv[0] , vous obtiendrez donc un comportement indéfini si strlen(my_program_name) est supérieure à la mémoire déjà allouée pour argv[0] : buffer overflow, segfault ou toute autre fonction car UB