geany-plugins icon indicating copy to clipboard operation
geany-plugins copied to clipboard

Debugger: Fix debugging of multi-threaded programs

Open nomadbyte opened this issue 2 years ago • 17 comments

  • By the original design, the debugger allows thread context switching only interactively, while in the Call Stack pane (in Stopped mode). This is being handled directly through GtkTreeView::cursor-changed event.
  • However, this event was also getting triggered when clearing the latest thread's Call Stack after continuing the execution (Running mode).
  • This behavior does not seem to have being intended, and it lead to a number of issues: stepping hangs, corruption of GDB output processing, unnecessary attempts at opening of source files corresponding to thread's call-stack frames.
  • To avoid all of these issues, GtkTreeView::cursor-changed event is left unhandled while clearing the frames. Also the handler for thread-context switching is allowed processing only in debugger's Stopped mode to enforce the intended behavior.

Fixes #1069

nomadbyte avatar Apr 03 '22 22:04 nomadbyte

@elextr Anyone to review this to get it merged? I don't think it's being maintained by anyone current, so I worded in much detail in the commit message to explain both the cause and the fix.

nomadbyte avatar Apr 26 '22 02:04 nomadbyte

@nomadbyte yeah, its over 10 years since the maintainer listed contributed.

We don't usually summarily remove maintainers, but since there are no contact details in the file to check if they are still interested I think the plugin could be marked orphaned so someone else can take over, if nobody objects (and someone reminds me) in a couple of weeks I'll do that @frlan @eht16 @b4n

elextr avatar Apr 26 '22 03:04 elextr

@nomadbyte yeah, its over 10 years since the maintainer listed contributed.

We don't usually summarily remove maintainers, but since there are no contact details in the file to check if they are still interested I think the plugin could be marked orphaned so someone else can take over, if nobody objects (and someone reminds me) in a couple of weeks I'll do that @frlan @eht16 @b4n

I'd look at who committed recently and ask whether they'd be willing to maintain it, but as far as removing maintainership information I really it's fine 10 years later :)

b4n avatar Jun 06 '22 11:06 b4n

Just for the record, a comment about the fix to @nomadbyte , i have been using the debugger with very good results with Geany 1.37 (git >= 5cc69b3d) . I don't know if anyone else tested this fix with newer Geany. I was more interested in debugging multi-threaded applications but recently i had to debug minicom to mimic some of its features in one local application here and depending on where i set the breakpoint (in minicom), the next [Step over] closes Geany. minicom is a terminal program generally used to communicate with some hardware via Serial/USB interface (most common use). If you are interested in knowing more about the issue, please let me know. Or if someone would like to find more, a tip to debug minicom is to comment the setjmp() code and then you are able to set breakpoints anywhere. Maybe the interrupts set by minicom are the main cause. BR.

avafinger avatar Jun 06 '22 15:06 avafinger

... If you are interested in knowing more about the issue, please let me know.

@avafinger, you could try to see if the same steps work properly in command-line GDB without Geany.

If the issue is persistent in Geany, then you may describe it in a new issue against the Debugger plugin.

nomadbyte avatar Jun 06 '22 16:06 nomadbyte

@nomadbyte I will do as you suggested. There are many signal handlers there that might trigger some weird thing.

By the way, your patch cannot be applied over the last one, i had to manually change the code. It works as expected. ;)

avafinger avatar Jun 06 '22 23:06 avafinger

@nomadbyte, I think i found the reason. The problem is with [Step into] and not [Step over] as i mentioned. Please, see if you can advise how to overcome the error. In fact, the debugger closes the debugging section and not Geany.

Below is the error:

sudo gdb --args ./minicom -D /dev/ttyUSB1

GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./minicom...done.
(gdb) b 77
Breakpoint 1 at 0x5365: file minicom.c, line 77.
(gdb) s
The program is not being run.
(gdb) run
Starting program: /apps/minicom-2.7.1/debian/minicom/usr/bin/minicom -D /dev/ttyUSB1
Lockfile is stale. Overriding it..

Breakpoint 1, port_init () at minicom.c:77
77	  m_setparms(portfd, P_BAUDRATE, P_PARITY, P_BITS, P_STOPB,
(gdb) s
78	             P_HASRTS[0] == 'Y', P_HASXON[0] == 'Y');
(gdb) s
77	  m_setparms(portfd, P_BAUDRATE, P_PARITY, P_BITS, P_STOPB,
(gdb) s
m_setparms (fd=3, baudr=0x5555557866e0 <mpars+4032> "1500000", 
    par=0x555555786800 <mpars+4320> "N", bits=0x555555786770 <mpars+4176> "8", 
    stopb=0x555555786890 <mpars+4464> "1", hwf=1, swf=0) at sysdep1.c:396
396	{
(gdb) s
397	  int spd = -1;
(gdb) s
399	  int bit = bits[0];
(gdb) s
408	  if (portfd_is_socket)
(gdb) s
413	  tcgetattr(fd, &tty);
(gdb) s
__GI___tcgetattr (fd=3, termios_p=0x7fffffffde30)
    at ../sysdeps/unix/sysv/linux/tcgetattr.c:34
34	../sysdeps/unix/sysv/linux/tcgetattr.c: No such file or directory.
(gdb) s
38	in ../sysdeps/unix/sysv/linux/tcgetattr.c
(gdb) s
34	in ../sysdeps/unix/sysv/linux/tcgetattr.c
(gdb) s
38	in ../sysdeps/unix/sysv/linux/tcgetattr.c
(gdb) s
40	in ../sysdeps/unix/sysv/linux/tcgetattr.c
(gdb) s
46	in ../sysdeps/unix/sysv/linux/tcgetattr.c
(gdb) s
63	in ../sysdeps/unix/sysv/linux/tcgetattr.c
(gdb) s
42	in ../sysdeps/unix/sysv/linux/tcgetattr.c
(gdb) s
63	in ../sysdeps/unix/sysv/linux/tcgetattr.c
(gdb) s
42	in ../sysdeps/unix/sysv/linux/tcgetattr.c
(gdb) n
Warning:
Cannot insert breakpoint 0.
Cannot access memory at address 0x1ec4635941ad2a3e

__longjmp () at ../sysdeps/x86_64/__longjmp.S:45
45	../sysdeps/x86_64/__longjmp.S: No such file or directory.
(gdb) 

I know i have to install libc6 sym, but can't remember how...

avafinger avatar Jun 06 '22 23:06 avafinger

@avafinger tcgetattr() is a linux library call so you can't set a breakpoint in it as its read only.

elextr avatar Jun 07 '22 00:06 elextr

Yes, but the breakpoint is not in tcgetattr(). The s (Step into) wants the source. I would expect that gdb would just skip the sysdeps function if not found. The GDB way is to tell gdb where the sysdeps source code is, but i think must be a better way.

(gdb) s
413	  tcgetattr(fd, &tty);
(gdb) s
__GI___tcgetattr (fd=3, termios_p=0x7fffffffde30)
    at ../sysdeps/unix/sysv/linux/tcgetattr.c:34
34	../sysdeps/unix/sysv/linux/tcgetattr.c: No such file or directory.
(gdb) info source
Current source file is ../sysdeps/unix/sysv/linux/tcgetattr.c
Compilation directory is /build/glibc-CVJwZb/glibc-2.27/termios
Source language is c.
Producer is GNU C11 7.5.0 -mtune=generic -march=x86-64 -g -O2 -O3 -std=gnu11 -fgnu89-inline -fmerge-all-constants -frounding-math -fstack-protector-strong -fPIC -ftls-model=initial-exec -fstack-protector-strong.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
(gdb) frame 1
#1  0x000055555557556f in m_setparms (fd=3, 
    baudr=0x5555557866e0 <mpars+4032> "1500000", 
    par=0x555555786800 <mpars+4320> "N", bits=0x555555786770 <mpars+4176> "8", 
    stopb=0x555555786890 <mpars+4464> "1", hwf=1, swf=0) at sysdep1.c:413
413	  tcgetattr(fd, &tty);

avafinger avatar Jun 07 '22 00:06 avafinger

The missing source is ok, in above you stepped into tcgetattr() stepped along a bit which was fine even if no source was shown, then did next not step. I would guess tcgetattr() does a trap to the kernal, and thats probably not tracable by GDB, which then gets very confused trying to do next. Debugging should work ok if you step over the call to tcgetattr() not into it.

elextr avatar Jun 07 '22 00:06 elextr

You are right, n can step over without throwing an error. I need to find a way to install the sources in case i inadvertently hit [Step into]. :)

avafinger avatar Jun 07 '22 00:06 avafinger

I doubt the source will make it work any better, thats only displayed for the human, GDB doesn't use it. :-)

elextr avatar Jun 07 '22 01:06 elextr

@avafinger, If the minicom-bound issue is not directly related to this multi-threaded debugging issue, I'd rather see this topic discussed in a separate issue for clarity and completeness.

The current "patch" should be functionally equivalent to my original fix; this just addresses the comments raised by @b4n . Thus, any Debugger issues possibly exposed by debugging the minicom code should be summarized in a new issue.

nomadbyte avatar Jun 07 '22 01:06 nomadbyte

Looking back, this may also fix the symptoms in #309 (Error 'Can't find a source file')

nomadbyte avatar Jun 07 '22 06:06 nomadbyte

Sorry, i didn't want to flood the thread. The minicom issue has nothing to do with your patch and is related to gdb only. And reading gdb threads here and there the fix is telling gdb where libc6 source code is, or never, ever step in into libc6 sys function. Update: you can close it. And i applied your patch over the already patched code and not from a clean code.

avafinger avatar Jun 07 '22 12:06 avafinger

@nomadbyte and others,

I opened a new issue to discuss the [Can't find a source file and no directory or file]. Please, make your considerations there. https://github.com/geany/geany-plugins/issues/1179

avafinger avatar Jun 07 '22 18:06 avafinger

@elextr I wonder if this PR is ready for the merge?

nomadbyte avatar Aug 25 '22 14:08 nomadbyte