web-server icon indicating copy to clipboard operation
web-server copied to clipboard

Cryptic contract violation from with-current-saved-continuation-marks-and

Open LiberalArtist opened this issue 6 years ago • 5 comments
trafficstars

After refactoring a big web-server program, attempting to run it now blames one of my modules for violating the contract of with-current-saved-continuation-marks-and ("expected 1 value, returned 2 values in: the range of the 3rd argument of (-> any/c any/c (-> any/c) any/c)"—full message below).

I am not sure how to minimize this example. The blamed module doesn't use with-current-saved-continuation-marks-and directly (nor does any of my code), and it doesn't even seem to use or define any functions with multiple return values. It is written in a language based on #lang web-server. (Changing to the plain #lang web-server doesn't seem to help.)

The bug seems to be the web server's fault: changing the blamed module to use #lang racket/base seems to fix the error. (It isn't clear why this module was in a web-server-based language in the first place: my guess is that I left it that way in an earlier refactoring.)

The contract problem happens both in Racket 7.4 CS and in traditional Racket built from master, but Racket CS has an additional problem: if I try to run the blamed module directly (i.e. racket portal/private-servlet/feedback/notify.rkt) when it's #lang is either web-server or my web-server-based language, Racket 7.4 CS has an "invalid memory reference," whereas traditional Racket succeeds.

Here's the full error message:

Sapientia:ricoeur-portal philip$ ./config/no-voyant-test.rkt 
with-current-saved-continuation-marks-and: contract violation;
 expected 1 value, returned 2 values
  in: the range of
      the 3rd argument of
      (-> any/c any/c (-> any/c) any/c)
  contract from: 
      <pkgs>/web-server-lib/web-server/lang/abort-resume.rkt
  blaming: <pkgs>/ricoeur-portal/portal/private-servlet/feedback/notify.rkt
   (assuming the contract is correct)
  at: <pkgs>/web-server-lib/web-server/lang/abort-resume.rkt:244.2
  context...:
   /Users/pltbuild/build/plt-release-64/bundle/racket/collects/racket/contract/private/blame.rkt:347:0: raise-blame-error16
   loop
   /Users/pltbuild/build/plt-release-64/bundle/racket/collects/racket/contract/private/arrow-common.rkt:63:5
   call-with-values
   call-with-values
   call-with-values
   /Users/philip/code/ricoeur/ricoeur-portal/config.rkt:207:22: pr:proc
   call-with-values
   /Users/pltbuild/build/plt-release-64/bundle/racket/collects/racket/private/promise.rkt:103:0: force/generic
   /Users/philip/code/ricoeur/ricoeur-portal/config.rkt:217:21
   call-with-values
   body of (submod "/Users/philip/code/ricoeur/ricoeur-portal/config/no-voyant-test.rkt" main)
   temp37_0
   for-loop
   run-module-instance!125
   #%for-each

LiberalArtist avatar Aug 22 '19 23:08 LiberalArtist

While the code where I encountered this is not yet public (we're working on it), I could provide access if it would help to diagnose these issues. But I'm also happy to try to produce a more minimal example, though advice on what to look for would be helpful.

LiberalArtist avatar Aug 23 '19 18:08 LiberalArtist

In case it's useful, I'm attaching the output of raco expand for the blamed module: expanded.log (The .log extension is to appease GitHub.)

Running the macro stepper on this module causes an internal error (at least in 7.4 CS), so I'm also linking to its debugging dump: macro-stepper-error.rktd.gz (Note that the file is 16.2 MiB compressed: I'm hosting it myself, and I'll probably delete it when this issue is closed.)

LiberalArtist avatar Aug 24 '19 02:08 LiberalArtist

Try changing the contract to (any/c any/c (-> any) . -> . any); do you get a different error?

jeapostrophe avatar Aug 26 '19 22:08 jeapostrophe

Yes, changing the contract and running ./config/no-voyant-test.rkt instead has the web server start successfully and gives me this exception from within my servlet: Attempt to capture a continuation from within an unsafe context: '(#((#t send/suspend) #f) #((#t (lambda (request))) #f) #((#t (lambda (req))) #f) #((#t (lambda (req))) #f) #((#f stx) #f) #((#t start) #f)) I think, but still need to confirm, that this exception is from a bug in my code that I fixed on my master branch.

Running the problem file directly (i.e. racket portal/private-servlet/feedback/notify.rkt) still produces an invalid memory reference on 7.4CS.

Additionally, while in a raco setup triggered by raco pkg update --lookup --catalog https://pkgs.racket-lang.org --clone web-server, I got a "nonrecoverable invalid memory reference" that I can't reproduce. Here's the tail of the output, just in case it's helpful:

raco setup: 5 re-rendering: <pkgs>/fancy-app/main.scrbl
raco setup: 4 rendering: <pkgs>/racket-doc/file/scribblings/file.scrbl
raco setup: 3 rendering: <pkgs>/freecell/forked-games-cards/forked-cards.scrbl
raco setup: 7 rendering: <pkgs>/fra/fra/fra.scrbl
raco setup: 5 rendering: <pkgs>/freecell/scribblings/freecell.scrbl
raco setup: 6 rendering: <pkgs>/functional-doc/scribblings/data/functional.scrbl
raco setup: 1 rendering: <pkgs>/games/gl-board-game/gl-board-game.scrbl
nonrecoverable invalid memory reference

LiberalArtist avatar Aug 28 '19 18:08 LiberalArtist

Did you test with master? Looking at the transformation, I don't feel like there should actually be a restriction on single values in this case, but the error you quote is a different kind of problem.

jeapostrophe avatar Sep 01 '19 00:09 jeapostrophe