[so] fork, exec*

Lucian Adrian Grijincu lucian.grijincu at gmail.com
Tue Mar 10 23:14:16 EET 2009


2009/3/10 Lucian Cojocar <cojocar at gmail.com>:
>        /* alocare dinamica cu *alloc pentru parametri
>           execve */
>        if (execve(parametri) < 0) {
>                /* eroare execve */
>                /* eliberare parametri alocati dinamic */
> [...]
> Cum eliberez parametrii alocati dinamic in caz ca execve se executa cu
> succes?

Dacă execve se execută cu success nu te mai intersează nimic din
procesul ăsta: imaginea procesului va fi rasă. În loc se va încărca
imaginea executabilului pe care îl încarci, se va încărca loaderul,
loaderul va porni execuția și va încărca bibliotecile dinamice, va
chema funcțiile de inițializare a bibliotecilor, va chema funcțiile de
inițializare a executabilului tău, va mapa memorie pentru tot ce ai
nevoie și după alte nimicuri va chema main().

În momentul ăsta nu mai există nici o urmă a memoriei vechi. Singurele
chestii care mai rămân sunt niște date prin nucleu: tabela de fișiere
deschise, ș.a.
Argumentele pe care le pasezi tu în execve sunt citite de kernel, și
copiate în spațiul noului proces

> Daca apelul lui execve este cu succes acesta inlocuieste zona de memorie a
> procesului curent; ar trebui sa nu-mi mai pese de acei parametri alocati
> dinamic?
>
> P.S. valgrind --leak-check=full  --show-reachable=yes nu mi-a indicat niciun
> leak

Nici nu trebuia. Vezi și programul de mai jos.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>

static void print_addr(char * proces, char * argv[], char * env[])
{
    printf("procesul %s: "
	   "\t&argv=%p "
	   "\t&argv[0]=%p "
	   "\t&environ=%p\n",
	   proces, &argv, &argv[0], &env);
}

int main(int argc, char *argv[], char * env[])
{
  char *newargv[] = { NULL, "--print-args", NULL } ;
  char *newenviron[] = { NULL } ;

  if (argc == 1) {
    /* program pornit fara argumente */
    print_addr("parinte", newargv, newenviron);


    // facem execve pe acelasi program, dar cu argumente diferite
    newargv[0] = argv[0];
    execve(argv[0], newargv, newenviron);
    perror("execve");   /* execve() only returns on error */
    exit(EXIT_FAILURE);
  }


  /* program pornit cu argumente diferite */
  print_addr("copil", argv, env);

  return 0;
}


gringo at lethe:~/labs/so/execve$ gcc check.c
gringo at lethe:~/labs/so/execve$ ./a.out
procesul parinte: 	&argv=0xbf85db84 	&argv[0]=0xbf85db94 	&environ=0xbf85db88
procesul copil: 	&argv=0xbf85e6b4 	&argv[0]=0xbf85e774 	&environ=0xbf85e6b8



-- 
 .
..: Lucian


More information about the so mailing list