racket / racket/drracket

DrRacket errortrace annotates macro-introduced code

Open
#157 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Racket
Stars
516
Forks
103
PR merge metrics
No merged PRs in 30d

Description

This issue describes one of the root causes of https://github.com/racket/htdp/issues/42.

The problem

Macro-introduced expressions in a file evaluated by DrRacket with debug turned on are always errortrace annotated, even when they originate from a file that was not errortrace annotated. For example, if an installed package with collection foo includes bar.rkt that is compiled to bytecode without errortrace annotation:

#lang racket
(define-syntax-rule (m f)
  (define (f arg)
    (error 'bad "bad")))
(provide m)

And I run baz.rkt, which is installed in a different package, in DrRacket:

#lang racket
(require foo/bar)
(m f)
(define (g arg)
  (f arg))
(g '())

The resulting stacktrace includes an entry for (error 'bad "bad"), but not for (f arg), because the macro-introduced (error 'bad "bad") expression was annotated and thus its continuation mark overwrites that from (f arg).

I'm not certain of the design intent here, but it seems as though DrRacket tries to avoid pointing to internals of library implementations when reporting errors unless those library implementations are in the same package as the file being run or some file from the implementation package is open in DrRacket for editing. For example, the stacktrace for:

#lang racket
(define (f x)
  (first x))
(f 5)

includes the call to (first 5) and not any location within the implementation of first in racket/list. The behavior for macro-introduced code seems inconsistent with this.

Likely cause

DrRacket overrides current-eval here with an implementation that expands syntax with a stack checkpoint wrapped around before passing it along.

That means that syntax that reaches the errortrace current-compile handler installed here will already be fully-expanded, so the dance errortrace does with the errortrace:annotate property to avoid annotating introduced syntax doesn't help.

I don't understand the design of the overridden current-eval well enough to have an idea of how to fix things. I'm not sure why

(current-eval
  (let ([oe (current-eval)])
    (lambda (sexp/syntax) 
       (with-stack-checkpoint
          (oe sexp/syntax)))))

wouldn't suffice.

I'm happy to work on a fix if someone can point me in the right direction!

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read drracket/drracket/private/rep.rkt around lines 1313-1348 and drracket/drracket/private/language.rkt around line 573, then trace the overridden current-eval and current-compile flow for expanded syntax. Compare it with the simpler current-eval wrapper described in the issue. Done means macro-introduced expressions from non-annotated libraries no longer replace the relevant caller in DrRacket error traces.

Written by the indexing model from the issue text.

Assessment

Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.