Atascado en el libro GDB de Stallman tratando de depurar m4 (procesador de macros) ejemplo de ‘error’: el ejecutable m4 que tengo es un contenedor directo en /bin (nada “…/gnu/ ./m4”)

7 minutos de lectura

avatar de usuario de nostromo
nostromo

(Hay otra publicación aquí en Stackoverflow: (¿Qué versión de m4 usa el autor de Depuración con GDB?), pero los enlaces a los que se hace referencia están rotos y la solución no parece muy profunda ni precisa. Tengo que decir que los probé y también intenté buscar en otras versiones m4 en el repositorio gnu, pero incluso eso: “len_lquote = strlen(lquote);” parece obsoleto desde la versión 2006, la más antigua que encontré).

EXPLICACIÓN MUY FÁCIL: el primer ejemplo en el libro Stallman GDB se refiere a un ejecutable “./m4” (primera sensación extraña con ese “./”), supuestamente presente en algunas (¿alguna instalación estándar antigua, quizás?): /gnu/ m4 (?) o /work/Editorial/gdb/gnu/m4/ (?) (y como señalé, parece ejecutarse con ‘./’ como si no fuera un entorno ejecutable [like mine. My “m4” that i installed through “sudo apt install m4” for the purpose]).

El problema es que si ejecuto “gdb m4”, no hace nada similar con el m4 del libro: DEBERÍA SER (por ejemplo, establecer un punto de interrupción en una función CONOCIDA. CONOCIDA, porque supongo que debería ser algún .c o algo así que GDB debería cargar/consultar en paralelo con el ejecutable, ¿no?):

(gdb) break m4_changequote 
Breakpoint 1 at 0x62f4: file builtin.c, line 879.

MÍO:

$ gdb m4               
GNU gdb (Debian 12.1-4+b1) 12.1 Copyright (C)
2022 Free Software Foundation, Inc. (......) Reading symbols from
m4... (No debugging symbols found in m4) 

(gdb) break m4_changequote
Function "m4_changequote" not defined. Make breakpoint pending on
future shared library load? (y or [n]) n

¿Alguna ayuda ÚTIL (directa al punto)? ¿Alguna solución? ¿Algún camino EQUIVALENTE?

  • ¿No hay enlace a esa publicación entonces?

    – Mike Solar

    11 de febrero a las 11:12

  • wiki.debian.org/HowToGetABacktrace

    – usuario17732522

    11 de febrero a las 11:18

  • Esta es puramente una pregunta sobre su distribución de Linux. Por lo general, no proporcionan símbolos de depuración automáticamente y debe consultar su documentación para saber cómo obtenerlos.

    – usuario17732522

    11 de febrero a las 11:19

  • user17732522, ¿quiere decir que si “habilito” esa función de rastreo (tengo que repasar eso primero), el ejemplo de Stallman funcionará? En esa publicación anterior que mencioné, el comentarista dice que tampoco es un error real y que fue “inyectado”. ¿Cómo resolverías este problema de inmediato? ¿Qué pasos directos daría desde mi posición para llegar a ese gdb sabiendo esa función y también estando seguro de que ese supuesto error ya está en ese objetivo m4? (porque el segundo laberinto sería, haciendo bien ese backtrace pero llegando a un m4 que funciona perfectamente buscando un error que no sale en absoluto). TY.

    – nostromo

    11 de febrero a las 11:45

  • ¿Por qué el Sr. Stallman no puso solo un ejemplo de “Hello World!”/hello-world.c-like? Esto inexplicable. (el caso es que estoy aprendiendo GDB en paralelo con otro libro y tiene ejemplos complejos. E ingenuamente pensé que el libro del creador iba a ser trivial, pero parece que no). Mejor usado un ejemplo a prueba de tiempo, no algo que “depende de una versión o una inyección…”. Parece que tiene que ser “de la manera difícil”. Gracias por tus ideas.

    – nostromo

    11 de febrero a las 11:50


Avatar de usuario de empleado ruso
Ruso empleado

EXPLICACIÓN MUY FÁCIL: el primer ejemplo en el libro Stallman GDB se refiere a un ejecutable “./m4” (primera sensación extraña con ese “./”), supuestamente presente en algunos (¿alguna instalación estándar antigua, tal vez?)

Está llegando a este problema con un conjunto incorrecto de suposiciones.

En general, usted más amenudo usar GDB en tus propios programas, es decir, programas que usted mismo codificó. Por lo general, depura estos programas en el directorio en el que los creó, que es el actual directorio. En UNIX, el directorio actual se llama .y si desea hacer referencia a un programa en su directorio actual, utilice ./program notación.

En el libro, Stallman está depurando m4 que trabajó y construyó.

Estás tratando de depurar m4 que tu no build, y por lo tanto tiene problemas para seguir el libro.

Te sugiero que descargues m4 fuentes y constrúyalo usted mismo (debería ser tan simple como ./configure && make), y entonces sigue el libro

Depuración del sistema proporcionado m4 también es posible, pero de eso no trata el libro.

Actualizar:

Hice mi tarea y revisé muchos archivos (.c, .h, etc.) en muchas carpetas de versiones m4 y no pude encontrar nada como lo que señalaste en tu publicación de 2009: “… Puedes descargar cualquier versión de m4, cambie len_lquote = strlen(lquote); a len_lquote = strlen(rquote); en set_quotes(), y luego rehaga la sesión de depuración de muestra. …”.

La publicación de 2009 a la que se hace referencia anteriormente es aparentemente esta.

yo descargué m4 versión usando:

git clone git://git.sv.gnu.org/m4
cd m4
git checkout branch-1.4

En src/input.cveo este código:

   719  void
   720  set_quotes (const char *lq, const char *rq)
   721  {
   722    free (lquote.string);
   723    free (rquote.string);
   724
   725    /* POSIX states that with 0 arguments, the default quotes are used.
   726       POSIX XCU ERN 112 states that behavior is implementation-defined
   727       if there was only one argument, or if there is an empty string in
   728       either position when there are two arguments.  We allow an empty
   729       left quote to disable quoting, but a non-empty left quote will
   730       always create a non-empty right quote.  See the texinfo for what
   731       some other implementations do.  */
   732    if (!lq)
   733      {
   734        lq = DEF_LQUOTE;
   735        rq = DEF_RQUOTE;
   736      }
   737    else if (!rq || (*lq && !*rq))
   738      rq = DEF_RQUOTE;
   739
   740    lquote.string = xstrdup (lq);
   741    lquote.length = strlen (lquote.string);
   742    rquote.string = xstrdup (rq);
   743    rquote.length = strlen (rquote.string);
   744  }

Evidentemente ya no hay len_lquote = strlen(lquote);pero la declaración equivalente es ahora lquote.length = strlen (lquote.string); en la línea 741.

Para introducir un error, cambiaría la línea 741 para que diga lquote.length = strlen (rquote.string);


Pero suponga que realmente quiere que la fuente coincida con lo que se describe en el libro. El libro se publicó por primera vez en 1988, y la primera versión de input.c en el repositorio de Git es de 2000, por lo que necesitamos encontrar una versión anterior de m4 fuentes.

Encontré una referencia a m4-1.0.3.tar.Z desde 1992 aquíy el archivo en sí aquí: http://www.nic.funet.fi/index/gnu/funet/historical-funet-gnu-area-from-early-1990s/m4-1.0.3.tar.Z

En ese archivo TAR, m4-1.0.3/input.c tiene la fuente que buscas:

   555  void
   556  set_quotes (char *lq, char *rq)
   557  {
   558    if (lquote != def_lquote)
   559      xfree (lquote);
   560    if (rquote != def_rquote)
   561      xfree (rquote);
   562
   563    lquote = (lq == NULL) ? def_lquote : xstrdup (lq);
   564    rquote = (rq == NULL) ? def_rquote : xstrdup (rq);
   565
   566    len_lquote = strlen (lquote);
   567    len_rquote = strlen (rquote);
   568  }

Cuidado: esa fuente es muy antigua y no se compila con compiladores modernos (GCC-12.2.0 en mi caso). Necesitará obtener una versión antigua de GCC para construirlo.

  • ¡Hola! Sr. @Employed Russian, sé que ./ es para decirle a Linux que ejecute un programa que está en el directorio actual. Obviamente soy muy respetuoso con el autor. El problema muy simple es que (y aquí acepto con gusto su punto sobre el “conjunto incorrecto de suposiciones”): al aprender una herramienta/tema, uno espera la menor cantidad de vientos en contra en ejemplos o material marginal. Incluso volviendo al ejemplo de m4, sería bueno proporcionar el código fuente incrustado (texto/apéndice) o hacer referencia a un repositorio o al menos a la versión del programa. Pensando también en la obsesión del autor por difundir el conocimiento.

    – nostromo

    11 de febrero a las 17:34

  • Pregunta directa: ¿sabes la versión donde vive este “bug” para no perder el tiempo descargando y compilando/enlazando versiones que funcionan perfectamente e incluso tienen funciones que no tienen nada que ver con las referidas en el texto? (Ya gracias por el consejo con la sugerencia configure && make. Otro conocimiento interesante. Muchas gracias).

    – nostromo

    11 de febrero a las 17:38

  • (Antes de publicar esta pregunta hoy), hice mi tarea y revisé muchos archivos (.c, .h, etc.) en muchas carpetas de versiones m4 y no pude encontrar nada como lo que señaló en su publicación de 2009: ” …Puede descargar cualquier versión de m4, cambiar len_lquote = strlen(lquote); a len_lquote = strlen(rquote); en set_quotes(), y luego rehacer la sesión de depuración de muestra. …”. Así que ya estoy bastante perdido.

    – nostromo

    11 de febrero a las 18:15


  • Muchísimas gracias. Aprenderé muchas cosas con tu explicación. Esto es oro para mí. Gracias por su esfuerzo. No tengo palabras.

    – nostromo

    11 de febrero a las 19:31

  • @nostromo Si la respuesta te ayudó, vótala. Si resolvió tu problema, acéptalo. Todos trabajamos por puntos marrones aquí 🙂

    – Ruso empleado

    11 de febrero a las 19:57

¿Ha sido útil esta solución?