Menu

#174 Breakpoints removed from editor are not removed from GDB

Next_Nightly
open
Bug_Report
2024-01-14
2015-06-05
No

In a debugging session, when I remove a breakpoint from the editor the breakpoint is not removed from GDB. To continue my work I have two options: Remove the breakpoint manually from GDB or open a new debugging session.

Setting the breakpoints works, the problem occurs only on removing or disabling.

I've already tried Code::Blocks version 13.12 and svn rev. 10253, 10314 and 10320.

Dell XPS 8300
Xubuntu 15.04 (Vivid) - Linux lucasggxps 3.19.0-15-generic #15-Ubuntu SMP Thu Apr 16 23:32:37 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
GDB 7.9 (I've already tried 7.8.2)

Related

Tickets: #1460

Discussion

  • Teodor Petrov

    Teodor Petrov - 2015-06-05
    • assigned_to: Teodor Petrov
    • Milestone: Undefined --> Next Nightly
     
  • Teodor Petrov

    Teodor Petrov - 2015-06-05

    Can you post the full debugger's log?
    Can you reproduce this problem with a simple project?

     
    • Lucas Guimarães

      This bug affects all projects.
      The problem occurs because the GDB output uses another language depending on locale settings.

      I have changed the system language to English and now I can remove and disable breakpoints!

      To reproduce you need to change your system language (locale) to Brazilian Portuguese (remember that I'm running on a Linux distribution). On Code::Blocks, set the breakpoint on some loop and then start the debugging session. Once started the debugging session, you need to remove the breakpoint and see that the debugger continues stopping at the line.

       

      Last edit: Lucas Guimarães 2015-06-06
  • Achim Schreiber

    Achim Schreiber - 2016-11-04

    Issue affects me as well, this is what i can provide:

    Code::Blocks 16.01, Ubuntu 12.04 64 bit
    default environment for tests:
    LANG="de_DE.UTF-8"
    LANGUAGE="de:en"
    LC_COLLATE="de_DE.UTF-8"
    LC_CTYPE="de_DE.UTF-8"
    LC_MESSAGES="de_DE.UTF-8"

    "toggle breakpoint" every 2nd time adds NEW breakpoint, every time with message "Haltepunkt %u at %p: file %s, line %u", breakpoint number incremented ("Haltepunkt" = breakpoint)
    otherwise no message, no change to breakpoints
    debugger console: "info breakpoints" confirms that
    after a couple of toggling, you end up with multiple same breakpoints
    "remove all breakpoints" does nothing, "info breakpoints" confirms that

    now only changing LANGUAGE does this:

    LANGUAGE="de_DE.UTF-8":
    same behaviour as "de:en"

    LANGUAGE="en_US.UTF-8":
    behaviour as intended:
    "toggle breakpoint" adds new breakpoint, without message - or deletes the correct breakpoint without message
    "remove all breakpoints" removes all breakpoints except #1 "exception throw", without message

     
  • Tiger Beard

    Tiger Beard - 2022-05-14

    This is from a forum post about this issue. The log covers a Breakpoint set in CB but not removed in gdb. The GUI side, both Editor and BP Window work consistently (all BPs I added or removed in the editor are added or removed in the BP window). Only the gdb side gdb differs. I included "<======" where I think the key points are. I can not attach the program and I did not manage to reproduce it with something small yet.

    The trace action was:

    • The program starts and hits one specific BP.
    • User selects Continue and it hits a second time.
    • The BP is removed in the Editor, the BP window also removes it from the list.
    • User selects continue.
    • GDB stops at the same position again (where both Editor and BP Window show no BP).
    • When the BP is set again, it shows in the BP window. Doing that a few times in the Debug log the BP numbers would increment each time (-> it does not reuse a deleted BP number).

    The BP from the test was BP6. The trace shows hitting it twice (which is OK). Deleteing it, however, deletes BP5. The BP Windows still shows BP5. When dbg continues it still has BP6 and of course stops there. When the BP is added in the editor again, it added "over" the first one, generating the last message.
    The trace shows a precularity with two BPs when they are initially set, an additional ">>>>>>cb_gdb:". Maybe meaningless.

    Active debugger config: GDB/CDB debugger:Default
    Building to ensure sources are up-to-date
    Selecting target: 
    DebugDll
    Starting debugger: /usr/bin/gdb -fullname -quiet  -args /home/..
    Setting SHELL to '/bin/sh'
    done
    [debug]> set prompt >>>>>>cb_gdb:
    
    Setting breakpoints
    
    [debug]Using terminal's PID as console PID 13700, TTY /dev/pts/5
    [debug]Queued:[tty /dev/pts/5]
    [debug]done.
    [debug](gdb) >>>>>>cb_gdb:
    Debugger name and version: GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
    
    [debug]Breakpoint 1 at 0x19fa02: file /home/
    [debug]>>>>>>cb_gdb:Breakpoint 2 at 0x19f3c4: file /home/                    <================
    [debug]Breakpoint 3 at 0x19f851: file /home/
    [debug]Breakpoint 4 at 0x1a6567: file /home/
    [debug]Breakpoint 5 at 0x29f59f: file /home/
    [debug]>>>>>>cb_gdb:Breakpoint 6 at 0x19fe19: file /home/                    <================ this is the correct BP
    [debug]> run
    [debug]Starting program: /home/
    
    [debug][New Thread 0x7fffea60f700 (LWP 13706)]
    [debug][New Thread 0x7fffe9e0e700 (LWP 13707)]
    
    [debug]Thread 1 "" hit Breakpoint 6, 
    [debug]/home/
    [debug]>>>>>>cb_gdb:
    
    At /home/
    Continuing...
    
    [debug]Thread 1 "" hit Breakpoint 6,                    <================ 2nd Hit. Deleting in in Editor
    [debug]/home/
    [debug]>>>>>>cb_gdb:
    
    At /home/
    [debug]>>>>>>cb_gdb:
    [debug]> x/256xb 0x0
    [debug]Cannot access memory at address 0x0
    [debug]0x0: >>>>>>cb_gdb:
    [debug]> delete breakpoints 5                    <================ BP6 is gone in Editor and BP Window. BP5 is still there in both windows
    [debug]>>>>>>cb_gdb:
    Continuing...
    [debug]> cont
    [debug]Continuing.
    [debug]Thread 1 "" hit Breakpoint 6,                    <================ no BP here, both in Editor nor Breakpoint windows
    [debug]/home/
    [debug]>>>>>>cb_gdb:
    At /home/
    [debug]>>>>>>cb_gdb:
    [debug]> x/256xb 0x0
    [debug]Cannot access memory at address 0x0
    [debug]0x0: >>>>>>cb_gdb:
    [debug]> break "/home/
    [debug]Note: breakpoint 6 also set at pc 0x5555556f3e19.                 <================ 
    [debug]Breakpoint 7 at 0x5555556f3e19: file /home/                    <================ this is receating the same BP in the editor
    [debug]>>>>>>cb_gdb:
    
     
  • Andrew Cottrell

    Andrew Cottrell - 2022-05-15

    GDB 8.1 is known to have issues and a such is NOT a good to test on.

     
  • Tiger Beard

    Tiger Beard - 2024-01-13

    I debugged the issue and I think I have found the root cause.

    Its in the DebuggerGDB's Option for User Init commands. This causes the above simple procedure to sometimes work or fail.

    To reproduce just add two two lines in the Options Init box (e.g. the following two lines) and the test will fail in any project with the first breakpoint set before the debugger is started. It can not be removed any more while the debugee runs, because its index in CB is -1. The GDB index is different.

       /home/user/ wxWidgets-3.0.5.1/misc/gdb/print.py
       skip file string.h
    

    The reason is that the parsing GDB replies fails at the breakpoints when more than one init line is entered.

    This is what happens: The two commands above will be sent as a single GDB command in the function

    GDB_driver::Prepare(...) 
          ...
          QueueCommand( new DebuggerCmd( this, init );    line 190
    

    where "init" is a string containing both lines entered into the text control above.

    It looks that these commands are queued together with all other initialization commands into the gdb command queue. After the queue is run, its expected that gdb completes the commands in the same order and sends replies for each. Thus the replies are parsed and assigned to the commands in the original order.

    The problem with the breakpoints is that gdb addresses them by index, but the index is returned only via the command output. When the parsing fails the index remains at -1 (invalid) and thus GDB will not recognize this breakpoint index and a delete command will fail.
    For the breakpoint the parsed line is processed by

         CDB_driver::ParseOutput( wxString& output)
           { 
           ....
           DebuggerCmd* cmd=CurrentCommand();
           if( cmd)
              ...
              RemoveTopCommand();
              cmd->ParseOutput( buffer);        # buffer is partially parsed output
              delete cmd;
           }
    

    The cmd calls the following function which eventually sets the correct breakpoint index.

      GdbCmd_AddBreakpoint::ParseOuput( wxString& output )
         ...
         reBreakpoint.GetMatch(output,1).ToLong(&m_BP->index);   
    

    Trouble starts when GDB returns more lines to parse then commands were sent. This gets worse the more lines are added in the init option box. GDB seems to understand multiple commands per line, but it does not return mutltiple returns in one line.
    In my test case with 2 line the "CurrentCommand()" started with 16 initial GDB commands but got 17 replies. Thus the reply for the Breakpoint line was parsed by the gdb "run" which was following the original break command.

    I can not see how the design is supposed to handle the replies to the user gdb init commands, maybe I overlooked something. Those commands were never parsed (only macro resolution is done). That means he debugger plugin does not know how many line there are and what commands are added by the user.

    The obvious workaround is to never use more than a single init command.

    I do not want to mess with a design I do not fully understand. But maybe a multiline text control could be a way to get a line count, insert some dummy commands to get the "QeueueCommand() - ParseOutput()" balanced.
    I do not really understand why the init lines must be sent in one go, but looking at some of the omments it seems to me that some people may do some quite sophisitcated stuff whith these init commands that is way over my head.

    Hopefully this insight is useful to reproduce and resolve the issue.

     

    Last edit: Tiger Beard 2024-01-13
  • Tiger Beard

    Tiger Beard - 2024-01-14

    Based on the proposal above I have implemented the test code below.

    The fix finds out how many init command line the user has added and adds for the surplus lines the dummy command "userInit". That should balance out with the GDB Parsing replies.

    The code does what it should but the results are not stable. When using multiple Breakpoints with multiple debugger starts, sometimes there is still a -1 index in there. I saw that the "ouput" string to parse sometimes contained 2 GDB prompts instead of one - maybe a timing issue on my compulter.
    However, its a definitive improvement so I will use this for my local version. Maybe its useful for further analysis.

    • old code
    void GDB_driver::Prepare(bool isConsole, int printElements, const RemoteDebugging &remoteDebugging) override
      {
    
      ...
      if (!init.empty())
            {
                QueueCommand(new DebuggerCmd(this, init));
            }
      ...          
    
    • new code
    void  GDB_driver::Prepare(bool isConsole, int printElements, const RemoteDebugging &remoteDebugging) override
      {
      ...
    
      if (!init.empty())
            {
                // issue for each user line n-1 dummy commands ("") and one command with all lines
                int nCount = 0;
                int nPos   = -1;
                wxString initCopy = init;
                nPos = initCopy.Find('\n');
                while( nPos != -1 )
                {
                    nCount++;
                    initCopy = initCopy.Right( initCopy.Length()-nPos-1 );
                    nPos = initCopy.Find('\n');
                }
                m_pDBG->DebugLog( wxString::Format("Found %d user init commands", nCount ));
                QueueCommand(new DebuggerCmd(this, init));
                for( int i=1; i<nCount; i++ )
                    QueueCommand(new DebuggerCmd(this, "userInit"));            // n-1 times
                }
    
            }
      ...       
    
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.