nostromo
nostromo

Reputation: 297

Stuck in Stallman's GDB book trying debug m4 (macro processor) 'bug' example: m4 executable I have is a direct bin in /bin (nothing ".../gnu/ ./m4")

(There is another post here in Stackoverflow: (Which version of m4 does the author of Debugging with GDB use?), but answer referred links are broken and the solution doesn't look much deep or to the point. I have to say I tried them and also tried to look in other m4 versions in the gnu repository, but even that: "len_lquote = strlen(lquote);" looks deprecated since 2006 version, oldest I found).

VERY EASY EXPLANATION: first example in Stallman GDB book refers to a "./m4" executable (first weird sensation with that "./"), allegedly to be present in some (some old standard installation, perhaps?): /gnu/m4 (?) or /work/Editorial/gdb/gnu/m4/ (?) (and as I pointed, it looks to be executed with './' like it was indeed not like an environment executable [like mine. My "m4" that I installed through "sudo apt install m4" for the purpose]).

The problem is that if I run "gdb m4", it doesn't do the anything similar with the book's m4: SHOULD BE (for example, setting a breakpoint in a KNOWN function. KNOWN, because I guess it should be some .c or something like that that GDB should load/consult in parallel with the executable, no?):

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

MINE:

$ 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

Any USEFUL (direct to the point) help? Any SOLUTION? Any EQUIVALENT path?

Upvotes: 2

Views: 162

Answers (1)

Employed Russian
Employed Russian

Reputation: 213754

VERY EASY EXPLANATION: first example in Stallman GDB book refers to a "./m4" executable (first weird sensation with that "./"), allegedly to be present in some (some old standard installation, perhaps?)

You are coming to this problem with the wrong set of assumptions.

In general, you most often use GDB on your own programs, i.e. programs you coded yourself. You usually debug these programs in the directory in which you built them, which is the current directory. On UNIX, current directory is named ., and if you want to refer to a program in your current directory, you use ./program notation.

In the book, Stallman is debugging m4 which he worked on and built.

You are trying to debug m4 which you didn't build, and thus you are having problems following the book.

I suggest that you actually download m4 sources and build it yourself (it should be as simple as ./configure && make), and then follow the book.

Debugging the system-provided m4 is also possible, but that's not what the book is about.

Update:

I did my homework and went through many files (.c, .h, etc) in many folders of m4 versions and i couldn't find anything like what you pointed back in your 2009 post: "...You can download any version of m4, change len_lquote = strlen(lquote); to len_lquote = strlen(rquote); in set_quotes(), and then redo the sample debugging session. ...".

The 2009 post referenced above is apparently this one.

I downloaded m4 version using:

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

In src/input.c, I see this code:

   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  }

Obviously there is no longer len_lquote = strlen(lquote);, but the equivalent statement is now lquote.length = strlen (lquote.string); on line 741.

To introduce a bug, you would change line 741 to read lquote.length = strlen (rquote.string);


But suppose you really want the source to match what was described in the book. The book was first published in 1988, and the very first version of input.c in the Git repo is from 2000, so we need to find older version of m4 sources.

I found a reference to m4-1.0.3.tar.Z from 1992 here, and the file itself here: http://www.nic.funet.fi/index/gnu/funet/historical-funet-gnu-area-from-early-1990s/m4-1.0.3.tar.Z

In that TAR file, m4-1.0.3/input.c does have the source you are looking for:

   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  }

Beware: that source is very old and does not build with modern compilers (GCC-12.2.0 in my case). You'll need to get an ancient version of GCC to build it.

Upvotes: 2

Related Questions