2

(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?

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
nostromo
  • 61
  • 1
  • 1
  • 11
  • 2
    No link to that post then? – Solar Mike Feb 11 '23 at 11:12
  • 1
    https://wiki.debian.org/HowToGetABacktrace – user17732522 Feb 11 '23 at 11:18
  • 2
    This is purely a question about your linux distribution. They typically do not provide debug symbols automatically and you have to look at their documentation for how to obtain them. – user17732522 Feb 11 '23 at 11:19
  • user17732522, do you mean that if i "enable" that backtrace feature (i have to go over that first), Stallman's example will work? I that old post that i mentioned, commentator says that isn't either a real bug and that was "injected". How would you solve this problem rightaway? Which direct steps would you make from my position to get to that gdb knowing that function and also being shure that that supposed bug is already in that m4 target? (because the second maze would be, doing that backtrace well but getting to a perfect functioning m4 looking for a bug that doesn't exit at all). TY. – nostromo Feb 11 '23 at 11:45
  • Why didn't Mr. Stallman put just a "Hello World!"/hello-world.c-like example? This inexplicable. (the fact is that i am learning GDB in parallel with another book and has complex examples. And i naively thought that the creator book was going to be trivial, but looks that not). Better used an example time-proof, not something that "depends on a versión or an injection...". Looks that it has to be "the hard way". Thank you for your ideas. – nostromo Feb 11 '23 at 11:50
  • @nostromo If you want to answer someone you should add the `@` in front of their username, otherwise they will not be notified. – user17732522 Feb 11 '23 at 11:59
  • @nostromo The page I linked only explains how to get the debug symbols for a package in Debian. (The page gives you several approaches.) You don't really care about backtraces, but the underlying issue is the same. I am not saying that the example will then work. But debug symbols are a prerequisite for useful debugging with a debugger. – user17732522 Feb 11 '23 at 12:01
  • @nostromo I have not read the book you refer to, but from a quick look it seems clear to me that the example is not meant to be replicated. It is a demonstration of a debug session, specifically about a _prerelease_ version of `m4` that you obviously wont have installed. It also reads like a documentation/reference about `gdb` itself and probably assumes that the reader already has the necessary background knowledge, including about debug symbols, probably compiling the program themselves, instead of using distribution packages. – user17732522 Feb 11 '23 at 12:06
  • @user17732522 Thank you! Very useful information!!! The debug symbols stuff (as is an unavoidable need). And the point that... "To know how to put a breakpoint" you don't need to use an old example in an exhaustive manner (the fact indeed is that if a go through unknown-for-me examples, i could grasp many implicit knowledge, not just gdb commands, but the agile and correct way of thinking when debugging: the same as doing the effort from going to "putting printf's all the way" instead of learning a debugger and getting the habit of using a debugger, all its language, methods and logic". TY. – nostromo Feb 11 '23 at 12:13
  • @user17732522 Last question! (never is with this announcement. LOL): When i was learning C++, i went through Bj. Str. book "Programming principles...". (HUGE IMPLICIT C++ KNOWLEDGE, not to mention Bj. "personal" libraries (f.e. "std_lib_facilities.h", etc), recursive mazes... Big (not that much because problems i found made me tougher and wiser) mistake, because when someone here in Stackoverflow addressed me Lippman's! Was a discover! Have you any suggestion for a good source for learning GDB? To steep the learning curve? Fighting programs in the raw & looking the web/pdfs everywhere? – nostromo Feb 11 '23 at 12:23
  • @nostromo Unfortunately I don't have anything at hand. Good material to teach debugging is even harder to come by than material to teach C (or C++). Personally I have learned most by just playing around with the debugger and searching through the docs, etc. That's not a good approach for learning the language itself because of the undefined behavior rules, but it should be fine to learn the debugger. Also look at how the ELF binary format works and what information you can find in it (e.g. the debug symbols) with a hex editor. Then you'll understand how the debugger gets its information. – user17732522 Feb 11 '23 at 12:55

1 Answers1

2

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.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Hi! Mr. @Employed Russian , i now that ./ is to tell linux to run a program that is in the current directory. I am obviously very respectful about the author. The very simple issue is that (and here i gladly accept your point on "wrong set of assumptions"): when learning a tool/topic, one expects the least headwinds in examples or marginal material. Even coming back to the m4 example, would be nice to provide the source code embedded (text/appendix) or referencing a repository or at least the version of the program. Also thinking about the obsession of the author of spreading knowledge. – nostromo Feb 11 '23 at 17:34
  • Direct question: do you know the version where this "bug" lives so i don't waste time downloading and compiling/linking versions that work perfectly and even have functions that have nothing to do with the ones referred in the text? (Already thank you for the advice with the configure && make hint. Another interesting piece of knowledge. Thank you very much). – nostromo Feb 11 '23 at 17:38
  • (Before posting this question today), 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. ...". So i am already quite lost. – nostromo Feb 11 '23 at 18:15
  • thank you very very very much. I will learn a lot of things from your explanation. This is gold for me. Thank you for your effort. I have no words. – nostromo Feb 11 '23 at 19:31
  • @nostromo If the answer helped you, upvote it. If it resolved your problem, accept it. We all work for browny points here :-) – Employed Russian Feb 11 '23 at 19:57
  • LOL. You are just wonderful! I am learning tons of things with this post. Not just technical! Political! Psychological! Everything! After your suggestion, i clicked on "accept" (never did before. I am very new to this. Information and rules where overwhelming. I am starting to digest and respond in good way to many things that community expect from me as for any other one. Today was like my first concious post editing). I tried to click the up arrow and y got this on a pop-up: "Thanks for the feedback! You need at least 15 reputation to cast a vote, but your feedback has been recorded". – nostromo Feb 11 '23 at 20:05
  • Even better! I reviewed old posts >> i could "accept" other answers >> that produced more reputation >> now i could press the up arrow" :D GREAT DAY! NO DOUBT! :D – nostromo Feb 11 '23 at 20:08
  • Wouldn't be possible to just do a `gcc -o m4 foo.c bar.c .... etc...` and generate an executable purely local to the folder to experiment directly with `GDB`(that is the main objective of all this) as to avoid overriding the exiting and up to date m4 installation (that is as well critical, as is a macroprocessor used for many applications). I can't understand what Mr. Stallman was thinking of when he had chosen this program, instead a 40 lines source code program easy typeable, instead of a system critical app... That was also going to be outdated in a couple of days. – nostromo Apr 26 '23 at 07:31
  • I waited a lot to do this because i was making my homework. Watching videos about `make` and `make install` (and also `git`!). Which are a new universe in themselves. And when i thought i had something, then i git cloned the m4 you found and appeared this unknown extensions `.ac` and back again to the first box. The question would be: tweaking autoconf/make flags, how could i build the m4 executable totally folder local avoiding making an unconvenient global m4 installation? Because overriding my native modern operating system m4, i think would be a mess. (Thx Russian, sorry for mssgs cascade) – nostromo Apr 26 '23 at 13:24
  • 1
    @nostromo You should ask a _new_ question -- it's free ;-) – Employed Russian Apr 26 '23 at 14:29