Steel Bank Common Lisp

backtrace ugliness when passing invalid number of arguments to cached gf

Reported by Tobias C. Rittweiler on 2010-01-04
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
SBCL
Medium
Unassigned

Bug Description

The following code

(defgeneric gf2 (x y)
  (:method (x y)
    (+ x y)))
(defun bar2 (z)
  (gf2 z))

exhibits the following backtrace behaviour.

First we call GF2 cold:

CL-USER> (bar2 1)
; Evaluation aborted.

And we get a reasonably looking backtrace. A perfect backtrace would
include (BAR2 1) and (GF 1) -- the latter is probably optimized away
because it's a tailcall.

The function
  #<STANDARD-GENERIC-FUNCTION GF2 (1)>
requires at least 2 arguments.
   [Condition of type SB-INT:SIMPLE-PROGRAM-ERROR]

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [ABORT] Return to SLIME's top level.
 2: [TERMINATE-THREAD] Terminate this thread (#<THREAD "repl-thread" RUNNING {B8DEFD9}>)

Backtrace:
  0: (SB-PCL::ERROR-NEED-AT-LEAST-N-ARGS #<STANDARD-GENERIC-FUNCTION GF2 (1)> 2)
  1: (SB-PCL::INITIAL-DFUN #<STANDARD-GENERIC-FUNCTION GF2 (1)> (1))
  2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (BAR2 1) #<NULL-LEXENV>)

Anyway, the problem is if we get GF2 into PCL caches:

CL-USER> (gf2 1 2)
3
CL-USER> (bar2 1)
; Evaluation aborted.

Now we get a very bad backtrace that does not only look bad, but
which is doubly bad because `v' in the debugger on the top frame
won't work, too. No fun to debug this.

invalid number of arguments: 1
   [Condition of type SB-INT:SIMPLE-PROGRAM-ERROR]

Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [ABORT] Return to SLIME's top level.
 2: [TERMINATE-THREAD] Terminate this thread (#<THREAD "repl-thread" RUNNING {B8DEFD9}>)

Backtrace:
  0: ((LAMBDA (SB-PCL::.ARG0. SB-PCL::.ARG1.)) 1)[:EXTERNAL]
  1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (BAR2 1) #<NULL-LEXENV>)

Changed in sbcl:
status: New → Confirmed
importance: Undecided → Medium
tags: added: compiler debugger pcl
Nikodemus Siivola (nikodemus) wrote :

Fixing after freeze:

diff --git a/src/pcl/methods.lisp b/src/pcl/methods.lisp
index c1e5fc4..efbd482 100644
--- a/src/pcl/methods.lisp
+++ b/src/pcl/methods.lisp
@@ -1414,7 +1414,7 @@
                         (make-dfun-lambda-list nargs applyp)
                         (make-fast-method-call-lambda-list nargs applyp))))
       (multiple-value-bind (cfunction constants)
- (get-fun1 `(lambda
+ (get-fun1 `(named-lambda (gf-dispatch ,name)
                       ,arglist
                       ,@(unless function-p
                           `((declare (ignore .pv. .next-method-call.))))

gets us:

0: ((SB-PCL::GF-DISPATCH GF2) 1) [external]
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (BAR2 1) #<NULL-LEXENV>)
2: (EVAL (BAR2 1))

In the first case GF2 isn't missing because

Nikodemus Siivola (nikodemus) wrote :

(Nevermind the last sentence above. Stray paste.)

Changed in sbcl:
assignee: nobody → Nikodemus Siivola (nikodemus)
status: Confirmed → In Progress
Nikodemus Siivola (nikodemus) wrote :

commit 021c2d16629a00103948405549f0d70fd5ec9ad9
Author: Nikodemus Siivola <email address hidden>
Date: Sat Jan 26 23:14:02 2013 +0200

    better debug name for secondary GF dispatch functions

     Fixes lp#503081

Changed in sbcl:
assignee: Nikodemus Siivola (nikodemus) → nobody
status: In Progress → Fix Committed
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers