2

我在 Allegro Common Lisp, v9.0 for Windows 中开发应用程序时偶然发现了一个非常奇怪的错误 (?)。我没有收到常规的 lisp 错误,而是将系统错误封装在 lisp 条件中。我设法创建了一个简单的测试用例来重现错误(这很愚蠢):

(defun lambda-producer ()
  (labels ((producer-label (x y)
                           (if (> x y) (- x y) (- y x)))
           (producer-label2 (x y)
                            (max (producer-label x 2) (producer-label y 3))))
  (lambda (x)
    (reduce (lambda (a b) (producer-label2 a b)) x))))

;; Get errors when calling:
(funcall (lambda-producer) (list 2 1 5 12))

每次尝试此测试用例时,我都会收到堆栈溢出错误。

在我的原始代码中,我遇到了很多错误,主要是分段错误,一旦出现“不能接受car<..> 因为它不是 listp”,并且一旦 Allegro 崩溃。

在 CLisp 中运行相同的代码段(或我的原始代码)时,一切运行正常,REPL 给出了答案。

我的问题:我在这里做错了什么或违法,还是 Allegro CL 中存在错误?如果是这样,我们能否确定该错误是什么以及如何处理它?


一些实验似乎表明reduceand 和双标签对于重现错误是必不可少的;替换reducefuncall或如果只有一个标签不会给出错误。

4

1 回答 1

4

这是一个编译器错误。请联系弗朗茨。

CG-USER(8): (disassemble (lambda-producer))
;; disassembly of #<Closure Template Function (:INTERNAL LAMBDA-PRODUCER 0)>
;; formals: X
;; closure vectors:
;;      0: #<Closure (LABELS LAMBDA-PRODUCER PRODUCER-LABEL2) @ #xdfdda7a>
;;      1: #<Function (LABELS LAMBDA-PRODUCER PRODUCER-LABEL)>
;; constant vector:
0: #<Closure Template Function (:INTERNAL (:INTERNAL LAMBDA-PRODUCER 0) 0)>
1: REDUCE

;; code start: #x21869018:
   0: 55          pushl ebp
   1: 89 e5     movl    ebp,esp
   3: 83 ec 38  subl    esp,$56
   6: 89 75 fc  movl    [ebp-4],esi
   9: 89 5d e4  movl    [ebp-28],ebx
  12: 39 63 1a  cmpl    [ebx+26],esp
  15: 76 03     jbe 20
  17: ff 57 43  call    *[edi+67]      ; SYS::TRAP-STACK-OVFL
  20: 83 f9 01  cmpl    ecx,$1
  23: 74 03     jz  28
  25: ff 57 8b  call    *[edi-117]    ; SYS::TRAP-WNAERR
  28: 8b 5d 00  movl    ebx,[ebp+0]
  31: 8b 5b ec  movl    ebx,[ebx-20]
  34: 8b 5b fa  movl    ebx,[ebx-6]
  37: 80 7f cb 00 cmpb  [edi-53],$0        ; SYS::C_INTERRUPT-PENDING
  41: 74 03     jz  46
  43: ff 57 87  call    *[edi-121]    ; SYS::TRAP-SIGNAL-HIT
  46: 8b 56 12  movl    edx,[esi+18] ; #<Closure Template Function (:INTERNAL (:INTERNAL LAMBDA-PRODUCER 0) 0)>
  49: ff b7 43 fe pushl [edi-445] ; SYS::CLOSURE-HEADER
      ff ff 
  55: 8f 45 d0  popl    [ebp-48]
  58: ff b7 47 fe pushl [edi-441] ; SYS::CLOSURE-ADDRESS
      ff ff 
  64: 8f 45 d4  popl    [ebp-44]
  67: 89 55 d8  movl    [ebp-40],edx
  70: 89 5d dc  movl    [ebp-36],ebx
  73: 8d 5d e2  leal    ebx,[ebp-30]
  76: 89 c2     movl    edx,eax
  78: 89 d8     movl    eax,ebx
  80: 8b 5e 16  movl    ebx,[esi+22] ; REDUCE
  83: ff 57 27  call    *[edi+39]      ; SYS::TRAMP-TWO
  86: 89 7d f0  movl    [ebp-16],edi
  89: c9          leave
  90: 8b 75 fc  movl    esi,[ebp-4]
  93: c3          ret

;; disassembly of #<Closure Template Function (:INTERNAL (:INTERNAL LAMBDA-PRODUCER 0) 0)>
;; formals: A B

;; code start: #x2186ccc0:
   0: 55          pushl ebp
   1: 89 e5     movl    ebp,esp
   3: 83 ec 30  subl    esp,$48
   6: 89 75 fc  movl    [ebp-4],esi
   9: 89 5d e4  movl    [ebp-28],ebx
  12: 39 63 1a  cmpl    [ebx+26],esp
  15: 76 03     jbe 20
  17: ff 57 43  call    *[edi+67]      ; SYS::TRAP-STACK-OVFL
  20: 83 f9 02  cmpl    ecx,$2
  23: 74 03     jz  28
  25: ff 57 8b  call    *[edi-117]    ; SYS::TRAP-WNAERR
  28: 8b 5d 00  movl    ebx,[ebp+0]
  31: 8b 5b ec  movl    ebx,[ebx-20]
  34: 8b 5b fa  movl    ebx,[ebx-6]
  37: 80 7f cb 00 cmpb  [edi-53],$0        ; SYS::C_INTERRUPT-PENDING
  41: 74 03     jz  46
  43: ff 57 87  call    *[edi-121]    ; SYS::TRAP-SIGNAL-HIT
  46: ff 73 f6  pushl   [ebx-10]
  49: 8f 45 dc  popl    [ebp-36]        ; EXCL::|local-0|
  52: 8b 75 dc  movl    esi,[ebp-36] ; EXCL::|local-0|
  55: 89 fb     movl    ebx,edi
  57: b9 02 00 00 movl  ecx,$2
      00 
  62: ff 57 23  call    *[edi+35]      ; SYS::FUNCALL-TRAMP
  65: 89 7d f0  movl    [ebp-16],edi
  68: c9          leave
  69: 8b 75 fc  movl    esi,[ebp-4]
  72: c3          ret
  73: 90          nop

在第二个闭包模板的 49 和 52 处,您可以看到它使用 2 个参数2将自己馈送到sys::funcall-tramp1


  1. sys::funcall-tramp是我认为可能执行或以其他方式允许尾调用的内部。

  2. 根据ecx57 的说法,因为ecx似乎用于检查是否sys::trap-wnaerr调用了内部;我wna代表错误数量的参数

于 2015-05-26T22:23:07.533 回答