Solaris: Navegando en el /proc (II)

Kernel, OpenSolaris Dejar un comentario

En el artículo anterior hablamos de los distintos ficheros y directorios que forman el sistema de archivos /proc, repasamos algunas de las estructuras de datos que forman dichos ficheros. En este artículo vamos a ver algunos ejemplos de cómo podemos crear nuestros propios comandos para obtener información de /proc, por una razón de tiempo no vamos a hablar de todos y cada uno de los ficheros.


El espacio de direcciones de un proceso lo podemos definir como la cantidad de memoria a la que el proceso puede acceder. Un espacio de direcciones está formando por, al menos, 4 segmentos, el segmento de texto, el segmento de datos, el heap y el stack. En el sistema de archivos /proc el SO mantiene un fichero el cual es una representación del mapa de direcciones /proc/< PID >/map. Empezaremos con un sencillo programa que nos permitirá representar el mapa de direcciones del espacio de direcciones de un proceso, el mismo resultado que podemos obtener con el comando pmap, salvando las distancias, claro está, lo que vamos a hacer es leer el contenido del fichero /proc/< PID >/map el cual está formando por un array de elementos de tipo struct prmap, este tipo de datos está definido en el fichero sys/procfs.h, la estructura prmap la forman, entre otros, los siguientes campos:

pr_vaddr Dirección de memoria del segmento
pr_size Tamaño en bytes del segmento
pr_mapname Nombre del fichero que está mapeado en el segmento.
pr_mflags Atributos del segmento.
pr_pagesize Tamaño de página del segmento.

El siguiente programa acepta como único parámetro el PID de un proceso, para abrir el fichero /proc/< PID >/map, como sabemos el fichero está formando por un array de elementos de tipo struct prmap.Programa proc_lwp_map.c

     1  #include < stdio.h >
     2  #include < sys/types.h >
     3  #include < sys/stat.h >
     4  #include < fcntl.h >
     5
     6  #define _STRUCTURED_PROC 1
     7
     8  #include < sys/procfs.h >
     9
    10  main(int argc, char **argv)
    11  {
    12
    13  int fd;
    14  char cadena[80];
    15  int pid;
    16  struct prmap pmap;
    17
    18  if (argc<2)
    19          {printf("Error: Falta el < pid >nn     Uso: %s < pid >nn",argv[0]);return;}
    20
    21  pid=atoi(argv[1]);
    22
    23  sprintf(cadena,"/proc/%d/map",pid);
    24  fd=open(cadena,O_RDWR);
    25
    26  if (fd<0)
    27  {printf("n Error: No se ha podido abrir el fichero %sn",cadena);return(1);}
    28
    29  printf("nAddrttSizetPSizetFlagstObject");
    30  printf("n-------------------------------------------------------n");
    31
    32  while((read(fd,&pmap,sizeof(struct prmap)))>0)
    33          {
    34          printf("n0x%.8lx",pmap.pr_vaddr);
    35          printf("t%dK",pmap.pr_size/1024);
    36          printf("t%dt",pmap.pr_pagesize);
    37
    38          if(pmap.pr_mflags & MA_READ)
    39                  {printf("r");}
    40                  else
    41                  {printf("-");}
    42
    43          if(pmap.pr_mflags & MA_WRITE)
    44                  {printf("w");}
    45                  else
    46                  {printf("-");}
    47
    48          if(pmap.pr_mflags & MA_EXEC)
    49                  {printf("x");}
    50                  else
    51                  {printf("-");}
    52
    53          if(pmap.pr_mflags & MA_SHARED)
    54                  {printf("s");}
    55                  else
    56                  {printf("-");}
    57
    58          if(pmap.pr_mflags & MA_ANON)
    59                  {printf("A");}
    60                  else
    61                  {printf("-");}
    62
    63                  printf("t%s",pmap.pr_mapname);
    64          }
    65
    66  close(fd);
    67  printf("n");
    68  }

Una vez que compilemos el programa, la salida de su ejecución será algo parecido a esto:

(root@huelva)# ./proc_lwp_map 520

Addr            Size    PSize   Flags   Object
-------------------------------------------------------

0x00010000      888K    8192    r-x--   a.out
0x000fe000      72K     8192    rwx--   a.out
0x00110000      224K    8192    rwx-A
0xfef60000      16K     8192    r-x--   ufs.273.0.73701
0xfef72000      16K     8192    rwx--   ufs.273.0.73701
0xfef80000      688K    8192    r-x--   ufs.273.0.2794
0xff03c000      32K     8192    rwx--   ufs.273.0.2794
0xff060000      40K     8192    r-x--   ufs.273.0.2791
0xff07a000      8K      8192    rwx--   ufs.273.0.2791
0xff080000      888K    8192    r-x--   ufs.273.0.2826
0xff16e000      40K     8192    rwx--   ufs.273.0.2826
0xff178000      24K     8192    rwx-A
0xff190000      8K      8192    rwx-A
0xff1a0000      8K      8192    r-x--   ufs.273.0.2808
0xff1b2000      8K      8192    rwx--   ufs.273.0.2808
0xff1c0000      8K      8192    r-x--   ufs.273.0.2833
0xff1d2000      8K      8192    rwx--   ufs.273.0.2833
0xff1e0000      24K     8192    r-x--   ufs.273.0.2852
0xff1f6000      8K      8192    rwx--   ufs.273.0.2852
0xff200000      568K    8192    r-x--   ufs.273.0.2839
0xff29e000      40K     8192    rwx--   ufs.273.0.2839
0xff2a8000      24K     8192    rwx-A
0xff2c0000      16K     8192    r-x--   ufs.273.0.2836
0xff2d4000      8K      8192    rwx--   ufs.273.0.2836
0xff2e0000      128K    8192    r-x--   ufs.273.0.2859
0xff300000      16K     8192    rwx--   ufs.273.0.2859
0xff310000      8K      8192    rwx-A
0xff320000      40K     8192    r-x--   ufs.273.0.2860
0xff33a000      8K      8192    rwx--   ufs.273.0.2860
0xff340000      248K    8192    r-x--   ufs.273.0.2850
0xff38e000      16K     8192    rwx--   ufs.273.0.2850
0xff3a0000      8K      8192    r-x--   ufs.273.0.3238
0xff3b0000      184K    8192    r-x--   ufs.273.0.1448
0xff3ee000      8K      8192    rwx--   ufs.273.0.1448
0xff3f0000      8K      8192    rwx-A
0xff3fa000      8K      8192    rwx--   ufs.273.0.2807
0xffbee000      72K     8192    rw--A
(root@huelva)#

La salida está compuesta por una serie de líneas, una por cada segmento que formen el espacio de direcciones del proceso, la primera es la dirección de memoria en la que podemos localizar el segmento, la última columna presenta el nombre del fichero que se ha mapeado en el segmento, el tamaño de un segmento no tiene por qué coincidir con el tamaño del fichero que se mapea, ya que puede que el segmento se mapee un trozo del fichero. El nombre el nombre del objeto está formado con el inodo del fichero que se está utilizando, podemos buscar el fichero cuyo inodo es 2794.

(root@huelva)# ls -li | grep 2794
      2794 -rwxr-xr-x   1 root     bin       867400 Dec 23  2004 libc.so.1
(root@huelva)#

El fichero cuyo inodo estamos buscando es una de las librerías que se han linkado en el ejecutable. Como podemos ver la salida es bastante parecida a la que obtendríamos con el programa pmap.

Navegando en el /proc (I)<< | >> Navegando en el /proc (III)

Technorati Tag(s) :

Los comentarios están cerrados.

My name is null, /dev/null
Algunos derechos reservados. Licencia Creative Commons