eclipse-cdt-cloud/cdt-gdb-adapter

Can not remove breakpoint when debugging

Opened this issue · 1 comments

Discussed in eclipse-cdt-cloud/cdt-cloud#42

Originally posted by wss29 July 2, 2024
I set a breakpoint in a loop code when debugging I click to remove the breakpoint, but I find it will be triggered at the point in the next loop

#include "Rectangle.h"
#include <windows.h>

void Rectangle::set_values(int x, int y)
{
  width = x;
  height = y;
}

void Rectangle::sleep(int millisecond)
{
  Sleep(millisecond);
}

int Rectangle::area()
{
  return width * height;
}
#include "Rectangle.h"
#include <iostream>
using namespace std;

int main()
{
  Rectangle rect, rectb;
  rect.set_values(3, 4);
  rectb.set_values(5, 6);
  cout << "rect area: " << rect.area() << endl;
  cout << "rectb area: " << rectb.area() << endl;

  int i = 20;
  while (i > 10)
  {
    rect.sleep(1000);
    cout << i << endl;
  }
  
  return 0;
}

2024-07-02_14-36-48

It looks like the logic that compares breakpoints is incorrect in regards (probably) to D: vs d: in Windows path. Extracted from the log (and edited for brevity):

[07:21:05.912 UTC] From client: setBreakpoints({"source":{"name":"main.cpp","path":"d:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp"},"sourceModified":false,"breakpoints":[{"line":19},{"line":22}],"lines":[19,22]})
[07:21:05.912 UTC] GDB command: 4 -break-list
-- here GDB replies to say no breakpoints exist in target as expected
[07:21:05.922 UTC] GDB command: 5 -break-insert "\"d:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp:19\""
[07:21:05.939 UTC] GDB command: 6 -break-insert "\"d:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp:22\""
-- at this point the two breakpoints are properly inserted

--- later when breakpointis removed from UI (as you can see only line 22 should now have a breakpoint)
[07:21:15.058 UTC] From client: setBreakpoints({"source":{"name":"main.cpp","path":"D:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp","sourceReference":0},"sourceModified":true,"breakpoints":[{"line":22}],"lines":[22]})

--- the adapter asks GDB what breakpoints are installed, and the return value shows the one at line 19 and 22
[07:21:15.058 UTC] GDB command: 39 -break-list
[07:21:15.063 UTC] GDB result: 39 done,BreakpointTable={nr_rows="2",nr_cols="6",hdr=[{width="7",alignment="-1",col_name="number",colhdr="Num"},{width="14",alignment="-1",col_name="type",colhdr="Type"},{width="4",alignment="-1",col_name="disp",colhdr="Disp"},{width="3",alignment="-1",col_name="enabled",colhdr="Enb"},{width="10",alignment="-1",col_name="addr",colhdr="Address"},{width="40",alignment="2",col_name="what",colhdr="What"}],body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x004015a8",func="main()",file="D:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp",fullname="D:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp",line="19",thread-groups=["i1"],times="4",original-location="d:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp:19"},bkpt={number="2",type="breakpoint",disp="keep",enabled="y",addr="0x004015ce",func="main()",file="D:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp",fullname="D:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp",line="22",thread-groups=["i1"
[07:21:15.063 UTC] GDB -cont-: 39 ],times="0",original-location="d:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp:22"}]}

--- but the adapter goes on to install an additional breakpoint at line 22:

[07:21:15.063 UTC] GDB command: 40 -break-insert "\"D:\\WorkGroup\\workspace\\workspace\\cpp\\src\\main.cpp:22\""

I think this happens because the first request from Theia has setBreakpoints of d: and the later one is D:.

The adapter relies on comparing original-location to identify matching files. Since the files don't match, we assume the second request is about a different file.

For the adapter we could use a case-insensitive comparison, but it would be really useful if Theia sent canonical file names to the backend too.