joaotavora / sly

Sylvester the Cat's Common Lisp IDE
1.26k stars 142 forks source link

On Allegro, unable to pop to sly-db buffer #543

Closed rpgoldman closed 1 year ago

rpgoldman commented 1 year ago

When I try to do this, I keep getting the error "Can't find a *sly-db* debugger for this context" from sly-db-pop-to-debugger-maybe.

Here's the recipe for replication:

  1. Start up Allegro CL in sly
  2. At this point optionally eval the variable sly-current-thread. When I do this, for some reason, it always evaluates to 13.
  3. Do something like this: (error "throw me into the debugger") to get a debugger window.
  4. If you eval sly-current-thread there, you get the same value (13).
  5. Get something into the inspector. What I did was:
    1. Type 'foo into the REPL
    2. Right click on the presentation for the symbol in the MREPL buffer and choose "Inspect"
  6. In the inspector window, eval sly-current-thread. It will be t.
  7. In the inspector window try to pop to the debugger, using "C-cld" which is bound to sly-pop-to-debugger-maybe
  8. Get error message "[sly] Can't find a *sly-db* debugger for this context"

The key issue seems to be the value of sly-current-thread. So I believe if I could inject the value of sly-current-thread into the sly popup windows, I could fix this issue.

When I try to find the value of this variable in various sly buffers I get quite different things:

  1. In the mrepl buffer: the number 13
  2. in *sly-description*: t
  3. in *sly-inspector for ...: t

So t means the current thread. When I pop up a debugger, the value of sly-current-thread there is 13. So I can't get to the debugger from the description or inspection buffers. Is this normal, or an ACL problem only?

Also, what is "the current thread"?

If anyone can help me figure out what is going on here, I can provide a fix. Looks like Allegro always has a thread number for its inferior lisp, and maybe the sly code expects that to be t ?

rpgoldman commented 1 year ago

Yes, I have verified that Allegro is starting up with sly-current-thread as 13 instead of t.

Presumably this means that my problems come from these other buffers not inheriting that value for sly-current-thread. I will investigate further.

rpgoldman commented 1 year ago

I have looked and it seems like both for the inspector and for a description window (haven't checked xref windows yet). Seems like when those windows are created they don't get the sly-current-thread binding. Any idea if solving my problem would be as easy as shoving that in?

joaotavora commented 1 year ago

Also, what is "the current thread"?

That is a key question i used to be able to answer it handily, but I can't anymore, not without reading as lot of code.

However, i see no description of what you are trying to do, from a user's perspective, other than the title of this issue, which is a bit sorry.I wonder if you can give a reproducible recipe from an Emacs -Q recipe that shows the error/inability you are referring to.

rpgoldman commented 1 year ago

@joaotavora Sorry I wasn't clear enough. I have revised the description of the issue above.

I believe I could fix this by sending the value of sly-current-thread in when invoking sly-with-popup-buffer. I will experiment with that. It seems that this variable is not explicitly being set, so it gets the default value of t which for (at least) Allegro does not work. I will check SBCL for comparison.

P.S. I am not sure I understand the relationship between a connection and a thread.

rpgoldman commented 1 year ago

Indeed, when I push the value of sly-current-thread into the new buffers, my problem goes away.

I did this by adding a :thread argument to sly-with-popup-buffer and binding it when creating inspector, cross-reference, or description buffers. I will create a PR.

rpgoldman commented 1 year ago

See #545

joaotavora commented 1 year ago

Get error message "[sly] Can't find a sly-db debugger for this context"

Robert, this message is absolutely true. There is no debugger for this context, because the inspection command you invoked runs in a different thread. In the SLYNK:*COMMUNICATION-STYLE* of :SPAWN, this how inspection and evaluation works: every new command spawns a new thread. So you can have multiple debuggers open, for example, tied to the stack trace of multiple threads. So, in general, associating threads id's to debuggers isn't correct.

BUT, you may get to inspect a value by hitting to the command loop of a specific thread, presumably stopped in a debugger. However, this is not what you did. You started an inspection by clicking something in the REPL, and I think that runs in a new thread (in the :spawn comm style).

I think it's just as if you had typed C-c I.

If you had typed i instead, then the inspection functions would indeed run in the stack trace of the debugger. You can see this by using it to evaluate something that signals an error, and checking out the stack trace:

 0: ((LAMBDA (#:G271)) #<unused argument>)
 1: ((LAMBDA NIL :IN SLYNK:INSPECT-IN-FRAME))
 2: (SLYNK::CALL-WITH-RETRY-RESTART "Retry SLY inspection request." #<FUNCTION (LAMBDA NIL :IN SLYNK:INSPECT-IN-FRAME) {1004F78DAB}>)
 3: (SLYNK::CALL-WITH-BUFFER-SYNTAX NIL NIL #<FUNCTION (LAMBDA NIL :IN SLYNK:INSPECT-IN-FRAME) {1004F78D8B}>)
 4: (SLYNK:EVAL-FOR-INSPECTOR NIL NIL SLYNK:INSPECT-IN-FRAME "(error \"here I am again!\")" 0)
 5: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SLYNK:EVAL-FOR-INSPECTOR NIL NIL (QUOTE SLYNK:INSPECT-IN-FRAME) "(error \"here I am again!\")" 0) #<NULL-LEXENV>)
 6: (EVAL (SLYNK:EVAL-FOR-INSPECTOR NIL NIL (QUOTE SLYNK:INSPECT-IN-FRAME) "(error \"here I am again!\")" 0))
 7: (SLYNK:EVAL-FOR-EMACS (SLYNK:EVAL-FOR-INSPECTOR NIL NIL (QUOTE SLYNK:INSPECT-IN-FRAME) "(error \"here I am again!\")" 0) NIL 46)
 8: (SLYNK::SLY-DB-LOOP 1)
 9: ((FLET SLYNK-BACKEND:CALL-WITH-DEBUGGING-ENVIRONMENT :IN "/home/capitaomorte/Source/Emacs/sly/slynk/backend/sbcl.lisp") #<FUNCTION (LAMBDA NIL :IN SLYNK::DEBUG-IN-EMACS) {535E492B}>)
10: (SLYNK::DEBUG-IN-EMACS #<SIMPLE-ERROR "throw me into the debugger" {100465A5F3}>)
11: (SLYNK:INVOKE-SLY-DEBUGGER #<SIMPLE-ERROR "throw me into the debugger" {100465A5F3}>)

It's only in this inspector (and similar inspectors) that I think the value of sly-current-thread should/could be set to the same as in the sly-db buffer. Does your patch guarantee that?

rpgoldman commented 1 year ago

Hm. Likely not. I wonder if I was over-fixing this and if the better solution would have been for me to simply rebind C-c l d to one of the other commands that does something like “find any available debugger” instead of this one which finds only the debugger for the current thread. It was bothersome to me that I would try to bounce back to the REPL or to the debugger and get this error message.

I rarely want to have C-c d Do anything other than jump me back to the debugger window because I rarely if ever have more than one debugger going, and it’s bothersome that I get this error. But now I can see why it is this way, because if you have multiple different threads you want to ensure you stay in the same context.

joaotavora commented 1 year ago

Hmm, I understand this "find any available debugger" case very well, because it's what I normally do. I just do it with Emacs's buffer switcher.

But you do bring up an interesting case, which is "switch to the debugger (if any) associated with the thread that spawned this inspection". And that's indeed not working. I'm just not sure your patch is the right way to fix it. But it might be :-)