Subject: Re: bug#5404: 23.1.91; Nextstep port: M-x gdb hangs in tab completion of symbols

From: Steve Revilak <[email-masked]>
Date: Sun, 24 Jan 2010 22:16:59 -0500

>From: Nick Roberts <[email-masked]>

>I think the terminal settings in the GUD buffer must be different for recent
>Macs.
>
>Try:
>
>(gdb) shell stty -onlcr
>
>(assuming "shell stty -a" gives onlcr).
>
>Emacs doesn't expect the extra ^M characters and so it fails to parse the
>output correctly.  If modifying the terminal doesn't work (but I think it
>should), you could try changing gud-gdb-marker-regexp and
>gud-gdb-marker-filter to look for ^M\n instead of just \n.

Nick,

I had the chance to try your suggestions with onlcr/-onlcr.  I wanted
to see how M-x gdb (and M-x gud-gdb) apply that terminal setting in
23.1.91; I also wanted to compare this with Emacs 22.3.

At the end of this message is an outline of the scenarios I've tried.
I'll summarize the high points:

  - Emacs 23 runs gdb with "onlcr".  Emacs 22 also used onlcr.  (Emacs
    22 did not exhibit the hanging or ^M behavior.)

  - In M-x gdb, changing onlcr to -onlcr prevents the hanging, but
    *only* if you make the change the terminal settings after gdb
    starts the target program.

  - The hanging in M-x gdb does NOT occur with M-x gud-gdb

  - with M-x gud-gdb, "shell stty -onlcr" makes the ^M's go away.

  - Looking through the code called by gud-gdb-complete-command, Emacs
    22 and Emacs 23 are practically identical.  In particular, 
    gud-gdb-marker-regexp and gud-gdb-marker-filter are the same.

I'd like to figure out why M-x gdb and M-x gud-gdb behave differently,
but I haven't gotten that far yet.

I know that Emacs 23 merged the GNUStep and MacOS code together (into
the nextstep port).  Could the behavior I'm seeing be the result of
something further down in the nextstep code?

I've tried to keep the outline terse.  If there are any points I
should clarify, please let me know.

Thanks again for all your guidance.  If you have any suggestions for
where to look next, please let me know.

Steve

==================================================================

* Emacs 23.1.91

  - Emacs -Q -nw ~/foo.c

  - M-x gdb RET
    Run gdb (like this): gdb --annotate=3 foo

  - At first (gdb) prompt, run "shell stty -a".  stty output shows
    "onlcr".

  - Run "shell stty -onlcr".  Afterwards, "shell stty -a" still shows
    "onlcr" (and not "-onlcr").  stty did NOT toggle the onlcr setting.

  - Type "b add_<TAB>".  This hangs, and has to be cancelled with C-g.

  - Type "b main RET", then "run RET".  GDB runs target program, stops
    at breakpoint in main.

  - Type "b add_<TAB>".  Still hangs, and has to be cancelled with C-g.
  
  - type "shell stty -onlcr".  This does something interesting.  Figure
    1 shows the "foo.c" buffer before I type "shell stty -onlcr".

---- Figure 1 ---------------------------------------------------
#include <stdio.h>

static int add_one(int x) {
   return (x + 1);
}

int main(void) {
=>int y = add_one(3);
   printf("%d\n", y);
   return 0;
}
------------------------------------------------------------------

   - after typing "shell stty -onlcr", the appearance of the foo.c
     buffer changes to Figure 2.  The code shifts two spaces to the
     right, and there is a `B' in column zero, to show where the
     breakpoint is set.

------- Figure 2 -------------------------------------------------
   #include <stdio.h>

   static int add_one(int x) {
     return (x + 1);
   }

   int main(void) {
B =>int y = add_one(3);
     printf("%d\n", y);
     return 0;
   }
------------------------------------------------------------------

  - type "shell stty -a".  This time "onlcr" has changed to "-onlcr"

  - "b add_<TAB>" does not hang.  It produces a list of completions
    (and no ^M's :)

OBSERVATION: before starting the target program, stty changes don't
seem to take effect.  After the target program starts running, stty
changes do take effect.  After "shell stty -onlcr",
gud-gdb-complete-command does not hang, and there are no ctrl ^M's.

This is at least a workaround.  Within the *gud-PROGRAM* buffer, run
"shell stty -onlcr" after the target program starts running, and don't
try to use symbol completion before the target program starts.

* Emacs 23.1.91 and M-x gud-gdb

M-x gud-gdb has an interesting variant on the above behavior.

  - Emacs -nw -Q ~/foo.c

  - M-x gud-gdb RET
    Run gud-gdb (like this): gdb --fullname foo

  - At first (gdb) prompt, "shell stty -a" shows "-onlcr".  This is the
    opposite behavior as M-x gdb

  - "b add_<TAB>" produces a list of completions.  It does not hang.
    There are no ^M's in the completion.

  - type "b main RET" then "run RET".

  - gdb starts running target program, and stops at first breakpoint.

  - "shell stty -a" shows "onlcr".  Starting the target program flipped
    -onlcr to onlcr.
    
  - "b add_<TAB>" does not hang, but each completion is suffixed with
    ^M (a behavior we discussed with the 23.1.90 release).

  - "shell stty -onlcr" changes onlcr back to "-onlcr"

  - "b add_<TAB>" produces a correct list of completions.

OBSERVATION: I also see another workaround.  After gdb starts the
program, "shell stty -onlcr" makes ^M go away.

* Comparing with Emacs 22.3

I tried this experiment with Emacs 22.3.  In Emacs 22.3,
gud-gdb-complete-command does not hang, and completions are not
suffixed with ^M.  I simply wanted to see what terminal settings M-x
gdb used in the older version.

  - Emacs-22.3 -Q -nw ~/foo.c

  - M-x gdb RET
    Run gdb (like this): gdb --annotate=3 foo

  - At first (gdb) prompt "shell stty -a" shows "onlcr" in Emacs-22.3.

  - type "b main RET".  Then "run RET"

  - when the breakpoint is hit, buffer "foo.c" looks like Figure 2.
    "shell stty -a" still shows "onlcr".

OBSERVATION: Both Emacs-22.3 and 23.1.91 use "onlcr" in terminal
settings.

* Comparing gud.el Between Emacs 22.3 and Emacs 23.1.91

I spent some time using M-x compare-buffers to look at the differences
between gud.el in Emacs 22.3 and Emacs 23.1.91.

There are NO differences in the following:

  - gud-gdb-complete-command
  - gud-gdb-run-command-fetch-lines
  - gud-gdb-fetch-lines-filter
  - gud-gdb-marker-regexp
  - gud-gdb-marker-filter

There is a small difference in gud-basic-call, but it looks like
nothing more than a change to eliminate "Warning: `save-excursion'
defeated by `set-buffer'".  

These symbols seem to cover the major steps in
gud-gdb-complete-command.