[racket] Breaks always go to main thread?

From: Greg Hendershott (greghendershott at gmail.com)
Date: Thu Mar 19 15:55:05 EDT 2015

Thank you, Robby.

> Another approach that you might want to try is to catch the "c:c;c:c"
> at the emacs level and instead of turning that into SIGINT (or
> whatever signal it is) send an explicit message across to the "(sync
> never-evt)" code that tells it to break the user's program's thread.
> This is closer to what DrRacket does and it has the advantage that you
> can still use the raw breaks to debug racket mode, should the need
> arise (I find this very useful when debugging drracket -- but no one
> expects a control-c to drracket to turn into breaking the program
> running inside drr!)

That's a good idea, too. Thanks!

Speaking of breaks and deubgging: I have a `debugger` branch (pushed to
GitHub, but not ready to be merged to master) with an experimental
debugger. It uses the annotations from gui-debugger, which was a huge
head start.

Instead of a separate watch window, it draws top-level and local binding
values directly in the source code buffer (somewhat like Light Table?).

On my first pass, I was thinking of debugging as a Special Mode you're
in, during which you break and resume etc., and then you exit. That
worked OK, but it was too modal and "too special".

So on my second (current) pass, you're in a special mode only while
you're at a breakpoint. And it's less special in the bad sense: Now
there's a full REPL available, extended with some debugging commands for
Emacs commands to use (or you could type them directly as a human). A
couple of the comamnds like ,(go) or ,(step) exit the special REPL and
resume execution; others don't.

And it's a normal REPL to eval code, not just for commands. In addition
to entering the module namespace, for read/write access to top-level
bindings, the prompt-read handler wraps your input in a let-syntax
mapping all local bound identifiers to set!-transformers. So you can
play with them interactively at the REPL. e.g.

    DEBUG:foot.rkt> (set! some-local (add1 some-local))

And so on, and eventually resume with those values in effect.

Currently you can break only via breakpoints (although there are various
flavors of these, including skip-N breakpoints, run-to-cursor, and so
on). I also want to support breaking as a result of:

1. A statement you could put in your source (like `debug` in Elisp, or
   `pry`, or whatever).

2. exn:break, although I'm not yet sure how that will work.

It's been fun to work on so far, although I'm scared I don't know what I
don't know, and there are probably huge gaping holes.

Posted on the users mailing list.