Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

realgud:gdb breakpoints out of sync after edit and recompile #268

Open
kenmcmil opened this issue Jun 1, 2020 · 6 comments
Open

realgud:gdb breakpoints out of sync after edit and recompile #268

kenmcmil opened this issue Jun 1, 2020 · 6 comments

Comments

@kenmcmil
Copy link

kenmcmil commented Jun 1, 2020

This is something that was always annoying about gdb mode and seems to happen also in realgud. If you edit the source and then recompile and restart the program in gdb, the breakpoint marks in the source files are out of sync with the breakpoints in gdb. That is, the the gdb breakpoints remain at the old line numbers, while the marks move with the edited text. What you really want is for the breakpoints to follow the source text, as they do in a typical IDE.

How about a command 'adjust-breakpoints' that moves the breakpoints in gdb to their current locations in the source files? This could be implemented by issuing a command to save the breakpoints in a file, modifying the file to reflect the line numbers of the marks, and then sourcing the file. For bonus points, when the 'run' command is issued, detect that the binary file has changed and call adjust-breakpoints automatically.

By the way, I just discovered realgud and am very happy to see that there is a replacement for the completely broken gdb-mi. Many thanks for that!

@rocky
Copy link
Collaborator

rocky commented Jun 1, 2020

How about a command 'adjust-breakpoints' that moves the breakpoints in gdb to their current locations in the source files?

Sure, this sounds reasonable. Want to implement it yourself?

This could be implemented by issuing a command to save the breakpoints in a file, modifying the file to reflect the line numbers of the marks, and then sourcing the file.

There may be some confusion about what realgud currently does. So let me explain.

In contrast to gdb, when last I looked implemented locations as a cons node whose car was a filename and cdr a line number, realgud in fact uses Elisp marks to mark a position.

That has implications. In particular if you insert/delete/modify text that doesn't encompass the marked position, the marked position stays contextually the same. And this is often what you want, unless this change has been coordinated with the debugger underneath and often it is not.

realgud uses a package called loc-changes found on ELPA/MELPA which manages the marks. It has a command loc-changes-clear-buffer that will remove marks for a single buffer.

When realgud terminates or notices debugger termination it issues this Elisp command to all the buffers attached from a central command buffer for that debugger session via the Elisp command realgud:terminate.

I am not sure how breakpoints are handled in this process and probably there are bugs here.

There is a place to associate additional commands to perform on a gdb run. That is in realgud:cmd-restart. At present though no additional commands are run.

Ok. Given the above, what one would do is add a command to run info breakpoints and parse the output of that command. Some of this is already done in realgud/common/buffer/breakpoint.el. It might just be a matter of reorganizing what gets run where.

I reread what you wrote, and I misunderstood. I had thought that the synchronization was to go from gdb to the realgud rather than the other way around. Synchronizing gdb from realgud as you suggest does indeed seem often times what you would prefer to do. Especially in the situation you describe.

For bonus points, when the 'run' command is issued, detect that the binary file has changed and call adjust-breakpoints automatically.

Sure that makes sense. realgud:cmd-restart is probably the place to hook this int.

By the way, I just discovered realgud and am very happy to see that there is a replacement for the completely broken gdb-mi. Many thanks for that!

Yes, I was unsatisfied enough with gdb and gdb-mi to undertake writing a replacement. With all of its warts and believe me I've been working around a number of them, it still is pretty cool after all of these years.

That said, I've been pretty much footing this activity all by myself. It is time to either get funding for this (fat chance) or get more people to help out. So thanks in advance.

@rocky
Copy link
Collaborator

rocky commented Jun 1, 2020

I just googled Ken McMillan - Wow! Z3 is way way way cool and has changed the landscape!. We used that in the Ethereum Mythril and Ethereum Solidity folks use that as well.

Many many many thanks for your work on this!

(I'm surprised you even took notice of this project because personally, I've been thinking about and moving towards VSCode, and LSP, and Debug protocols).

@kenmcmil
Copy link
Author

kenmcmil commented Jun 1, 2020

Well, I added a couple of features in Z3, but's it's really Leo DeMoura and Nikolaj Bjorner who are responsible for Z3. I'm just as in awe of them as you are!

I can try coding the 'adjust-breakpoints' feature if you can give me a few pointers. Looking at the code it seems that realgud-bp-add-info is where a new breakpoint marker is added. I was thinking maybe the thing to do is add a local variable to the command buffer that holds a map from breakpoint numbers to marks. Then adjust-breakpoints extracts from this a list of breakpoint/line number pairs that is passed to a debugger-specific routine that moves the breakpoints. This is not quite perfect, because breakpoints set at functions rather than line numbers should probably stay on those functions, which means the marks have to move. An annoying problem is that it doesn't seem possible to set the gdb breakpoint counter back to zero, so the moved breakpoints will have new numbers, but maybe that's not a big deal. I'll give it a try and bother you with questions if I run into trouble.

I'm not ready to switch to VSCode yet!

@rocky
Copy link
Collaborator

rocky commented Jun 1, 2020

I'm In New York, have to go to sleep now, but we will get this done.

@rocky
Copy link
Collaborator

rocky commented Jun 1, 2020

I looked again at the issue and I think I understand better the request. So I've modified what I wrote — see the crossed-out part and part after that. I was a bit tired and edgy yesterday and probably shouldn't have written anything in that state.

I was thinking maybe the thing to do is add a local variable to the command buffer that holds a map from breakpoint numbers to marks.

This is in fact already there in the command buffer. If you run realgud:cmdbuf-info-describe you will see the information listed there inside an org-mode buffer.

Here is an extract from a session I just tried:

Breakpoint list (bp-list)

Breakpoint 2

  • filename :: /home/rocky/c/ctest3.c
  • line number :: 14
  • brkpt num :: 2
  • source marker :: #<marker at 192 in ctest3.c>
  • cmdbuf marker :: #<marker at 2629 in gdb ctest3 shell>

Breakpoint 1

  • filename :: /home/rocky/c/ctest3.c
  • line number :: 10
  • brkpt num :: 1
  • source marker :: #<marker at 109 in ctest3.c>
  • cmdbuf marker :: #<marker at 2378 in gdb ctest3 shell>

The actual field in the debugger structure realgud-cmdbuf-info and shown above is called bp-list

This is not quite perfect, because breakpoints set at functions rather than line numbers should probably stay on those functions,

There is a realgud debugger remap command set aside called break-fn that could be used for this. However, right now it doesn't have a custom implementation so it just does a format string expansion. However a custom routine could be added to save a flag that indicates that the breakpoint is on a function, and cause realgud to behave differently with respect to relocation.

An annoying problem is that it doesn't seem possible to set the gdb breakpoint counter back to zero, so the moved breakpoints will have new numbers, but maybe that's not a big deal.

If it helps, when realgud--adjust-breakpoints is run it could save the old breakpoint number as a convenience for the user.

(About the longer name realgud--adjust-breakpoints: recall in GNU Emacs lisp, because of potential namespace clashes package commands should be prefaced with the package name; I believe the current convention is to add two dashes after the package name).

I'll give it a try and bother you with questions if I run into trouble.

No problem, no bother. Thanks again for offering to work on this! As in any open-source project, if it is to be successful and survive it has to rely on the help of more than primarily one person. And the project is definitely has already been made much better as a result of the suggestions and work of other people.

@rocky
Copy link
Collaborator

rocky commented Jun 1, 2020

An annoying problem is that it doesn't seem possible to set the gdb breakpoint counter back to zero, so the moved breakpoints will have new numbers, but maybe that's not a big deal.

It occurs to me that this is easy enough to change in the debuggers I control. Also, this could be suggested and changed in gdb. But as for the debuggers I control, I'd wait until there is a real use case first, i.e. after this goes in.

And in my opinion it after this is in place these other gdb-like debuggers, would I'd attempt to change it in gdb.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants