Buffer overflow with CFFI callback
Hi allSorry about this being a long mail, but I want the information to be complete...
Using a Midishare DLL with LWW6.0.1, I experience an error during a callback (MidiSetRcvAlarm) from the DLL telling me that a new MIDI event has arrived. My callback function is called with seemingly appropriate data, but then the error arrives when returning from the callback.
Sending MIDI events works as expected. I use the same lisp bindings on LWM6.0.1 without problems.
Code snippet, where midishare-receive is used to set up the callback function *midishare-recv*, which is used in the midishare-callback:
---
(cffi:defcallback midishare-callback :void ((refnum :short))
(restart-case
(handler-bind ((error
#'(lambda (c)
(declare (ignore c))
(invoke-restart 'callback-error-exit))))
(do ((ev (MidiGetEv refnum)
(MidiGetEv refnum)))
((or (not *midishare-recv*)
(cffi:null-pointer-p ev))
(values))
(funcall *midishare-recv* ev)))
(callback-error-exit ()
(format
t "~&Caught error under Midishare callback, aborting receive!~%")
(MidiFlushEvs refnum)
(MidiSetRcvAlarm refnum (cffi:null-pointer))
(values))))
(defun midishare-receive (refnum hook)
(when *midishare-recv*
(error "midishare-receive: already receiving."))
(setq *midishare-recv* hook)
(MidiSetRcvAlarm refnum (cffi:callback midishare-callback))
(values))
---
(cffi:defcallback midishare-callback :void ((refnum :short))
(restart-case
(handler-bind ((error
#'(lambda (c)
(declare (ignore c))
(invoke-restart 'callback-error-exit))))
(do ((ev (MidiGetEv refnum)
(MidiGetEv refnum)))
((or (not *midishare-recv*)
(cffi:null-pointer-p ev))
(values))
(funcall *midishare-recv* ev)))
(callback-error-exit ()
(format
t "~&Caught error under Midishare callback, aborting receive!~%")
(MidiFlushEvs refnum)
(MidiSetRcvAlarm refnum (cffi:null-pointer))
(values))))
(defun midishare-receive (refnum hook)
(when *midishare-recv*
(error "midishare-receive: already receiving."))
(setq *midishare-recv* hook)
(MidiSetRcvAlarm refnum (cffi:callback midishare-callback))
(values))
---
This is what I experience when the called back function returns:
Error in process: "Process for unknown thread42C"
Message:
Exception C0000005 [flags 0] at 10003A82
eax 0 ebx 0 ecx 10009288 edx 10009288
esp 6C3FE60 ebp 20060001 esi 10 edi 100093CE
Restarts:
(abort) Quit process.
Here is the short backtrace (a longer is available further down)
CL-USER 1 : 1 > :b
Call to INVOKE-DEBUGGER
Call to ERROR
Call to WIN32::SIGNAL-EXCEPTION-ERROR
Call to (SUBFUNCTION SYSTEM::|%FOREIGN-CALLABLE/lisp_signal_error_on_c_stack| (FLI:DEFINE-FOREIGN-CALLABLE "lisp_signal_error_on_c_stack"))
Call to MP::PROCESS-SG-FUNCTION
Call to INVOKE-DEBUGGER
Call to ERROR
Call to WIN32::SIGNAL-EXCEPTION-ERROR
Call to (SUBFUNCTION SYSTEM::|%FOREIGN-CALLABLE/lisp_signal_error_on_c_stack| (FLI:DEFINE-FOREIGN-CALLABLE "lisp_signal_error_on_c_stack"))
Call to MP::PROCESS-SG-FUNCTION
NOTES:
1. Exception C0000005 seems to mean Access Violation, which indicates a Buffer Overflow
2. By adding a sleep in the *midishare-recv* function, I have concluded that the exception happens when/after the midishare-callback returns.
3. If I make a minimal midishare-callback, which does not even call the *midishare-recv*, I still get the exception!?
Any thoughts?
Any help would be greatly appreciated!
Sven
--- start of long backtrace ---
CL-USER 2 : 1 > :bb
#<The COMMON-LISP-USER package, 28/64 internal, 0/4 external>
#<MP:PROCESS Name "Process for unknown thread42C" Priority 0 State "Running">
Condition: Exception C0000005 [flags 0] at 10003A82
eax 0 ebx 0 ecx 10009288 edx 10009288
esp 6C3FE60 ebp 20060001 esi 10 edi 100093CE
Call to ERROR (offset 67)
SYSTEM::ESTRING : WIN32::EXCEPTION
SYSTEM::EARGS : (:CODE 3221225477 :FLAGS 0 :ADDRESS 268450434 :FAULT-HANDLER-ARGS #(3221225477 0 0 268450434 2 0 0 65663 0 0 0 0 0 0 639 288 65535 541236949 27 33548740 65663 0 0 0 0 0 0 639 288 65535 541236949 27 33548740 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1074109952 0 0 59 35 35 268473294 16 0 268472968 268472968 0 537264129 268450434 27 66070 113507936 35 18875007 0 541236949 27 33548740 35 8064 65535 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2650800128 16389 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2300794030 0 2520676604 2300811687 2520676628 2300811937 2240456264 0))
Call to WIN32::SIGNAL-EXCEPTION-ERROR (offset 666)
Binding frame:
SYSTEM::*LISP-SIGNAL-ERROR-ON-UNKNOWN* : NIL
Call to (SUBFUNCTION SYSTEM::|%FOREIGN-CALLABLE/lisp_signal_error_on_c_stack| (FLI:DEFINE-FOREIGN-CALLABLE "lisp_signal_error_on_c_stack")) (offset 37)
FLI::%FOREIGN-CALL-STACK% : :DONT-KNOW
Call to SYSTEM::FOREIGN-CALLABLE-ENTRY-POINT-NEW-PROCESS-AUX (offset 36)
SYSTEM::FUNC : SYSTEM::|%FOREIGN-CALLABLE/lisp_signal_error_on_c_stack|
Catch frame: MP::PROCESS-TAG
Catch frame: (MP::PROCESS-SG-FUNCTION . 1)
Catch frame: (MP::PROCESS-SG-FUNCTION . 1)
Binding frame:
MP:*CURRENT-PROCESS* : NIL
Binding frame:
MP::*ACTIONS-AFTER-SLEEPING* : NIL
Binding frame:
MP::*ACTIONS-BEFORE-SLEEPING* : NIL
Binding frame:
SYSTEM::*READER-STATE* : #<SYSTEM::READER-STATE In 0 out 17 2179CCFB>
Binding frame:
*PACKAGE* : #<The COMMON-LISP-USER package, 28/64 internal, 0/4 external>
Binding frame:
WIN32::*PROCESS-DC* : NIL
Binding frame:
WIN32::*DDE-THREAD-INSTANCE* : #<Unbound Marker>
Binding frame:
EDITOR::*CURRENT-BUFFER* : NIL
Binding frame:
EDITOR::*CURRENT-WINDOW* : NIL
Binding frame:
EDITOR::*EDITOR-STATE* : NIL
Binding frame:
EDITOR::*EDITOR-INPUT-STYLE* : #S(EDITOR:EDITOR-INPUT-STYLE :KEY-BINDINGS #<EDITOR::KEY-TABLE #<EQUALP Hash Table{339} 2066CBAB> 1 338> :DELETE-SELECTION-MODE NIL :LOGICAL-CHARACTERS #<EQUALP Hash Table{22} 2063A23B> :EXECUTE-MODE #<EDITOR::MODE-OBJECT "Execute" 2070A86B> :ECHO-MODE #<EDITOR::MODE-OBJECT "Echo Area" 2070ACCF> :PLIST NIL :INTERRUPT-KEYS (#S(SYSTEM::GESTURE-SPEC :DATA 103 :MODIFIERS 2) #S(SYSTEM::GESTURE-SPEC :DATA 71 :MODIFIERS 2)) :STYLE :EMACS :POINT-ALWAYS-VISIBLE T :USE-FACE-TO-FULL-WIDTH-P T)
Binding frame:
CAPI::*USE-ACCELERATORS* : T
Binding frame:
CAPI-WIN32-LIB::*ALT-IS-META-KEY* : T
Catch frame: #:|progv-cathcer236969|
Call to MP::PROCESS-SG-FUNCTION (offset 509)
MP::STACK-ARG : NIL
MP::SYMBOLS : NIL
VALUES : NIL
Catch frame: SYSTEM::EXIT-FOREIGN-CALLABLE
Call to SYSTEM::FOREIGN-CALLABLE-ENTRY-POINT-NEW-PROCESS (offset 173)
SYSTEM::FUNC : SYSTEM::|%FOREIGN-CALLABLE/lisp_signal_error_on_c_stack|
Call to SYSTEM::%FUNCALL1-ON-LISP-STACK (offset 34)
SYSTEM::%FUNCALL1-ON-LISP-STACK
T
CL-USER 3 : 1 >
#<MP:PROCESS Name "Process for unknown thread42C" Priority 0 State "Running">
Condition: Exception C0000005 [flags 0] at 10003A82
eax 0 ebx 0 ecx 10009288 edx 10009288
esp 6C3FE60 ebp 20060001 esi 10 edi 100093CE
Call to ERROR (offset 67)
SYSTEM::ESTRING : WIN32::EXCEPTION
SYSTEM::EARGS : (:CODE 3221225477 :FLAGS 0 :ADDRESS 268450434 :FAULT-HANDLER-ARGS #(3221225477 0 0 268450434 2 0 0 65663 0 0 0 0 0 0 639 288 65535 541236949 27 33548740 65663 0 0 0 0 0 0 639 288 65535 541236949 27 33548740 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1074109952 0 0 59 35 35 268473294 16 0 268472968 268472968 0 537264129 268450434 27 66070 113507936 35 18875007 0 541236949 27 33548740 35 8064 65535 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2650800128 16389 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2300794030 0 2520676604 2300811687 2520676628 2300811937 2240456264 0))
Call to WIN32::SIGNAL-EXCEPTION-ERROR (offset 666)
Binding frame:
SYSTEM::*LISP-SIGNAL-ERROR-ON-UNKNOWN* : NIL
Call to (SUBFUNCTION SYSTEM::|%FOREIGN-CALLABLE/lisp_signal_error_on_c_stack| (FLI:DEFINE-FOREIGN-CALLABLE "lisp_signal_error_on_c_stack")) (offset 37)
FLI::%FOREIGN-CALL-STACK% : :DONT-KNOW
Call to SYSTEM::FOREIGN-CALLABLE-ENTRY-POINT-NEW-PROCESS-AUX (offset 36)
SYSTEM::FUNC : SYSTEM::|%FOREIGN-CALLABLE/lisp_signal_error_on_c_stack|
Catch frame: MP::PROCESS-TAG
Catch frame: (MP::PROCESS-SG-FUNCTION . 1)
Catch frame: (MP::PROCESS-SG-FUNCTION . 1)
Binding frame:
MP:*CURRENT-PROCESS* : NIL
Binding frame:
MP::*ACTIONS-AFTER-SLEEPING* : NIL
Binding frame:
MP::*ACTIONS-BEFORE-SLEEPING* : NIL
Binding frame:
SYSTEM::*READER-STATE* : #<SYSTEM::READER-STATE In 0 out 17 2179CCFB>
Binding frame:
*PACKAGE* : #<The COMMON-LISP-USER package, 28/64 internal, 0/4 external>
Binding frame:
WIN32::*PROCESS-DC* : NIL
Binding frame:
WIN32::*DDE-THREAD-INSTANCE* : #<Unbound Marker>
Binding frame:
EDITOR::*CURRENT-BUFFER* : NIL
Binding frame:
EDITOR::*CURRENT-WINDOW* : NIL
Binding frame:
EDITOR::*EDITOR-STATE* : NIL
Binding frame:
EDITOR::*EDITOR-INPUT-STYLE* : #S(EDITOR:EDITOR-INPUT-STYLE :KEY-BINDINGS #<EDITOR::KEY-TABLE #<EQUALP Hash Table{339} 2066CBAB> 1 338> :DELETE-SELECTION-MODE NIL :LOGICAL-CHARACTERS #<EQUALP Hash Table{22} 2063A23B> :EXECUTE-MODE #<EDITOR::MODE-OBJECT "Execute" 2070A86B> :ECHO-MODE #<EDITOR::MODE-OBJECT "Echo Area" 2070ACCF> :PLIST NIL :INTERRUPT-KEYS (#S(SYSTEM::GESTURE-SPEC :DATA 103 :MODIFIERS 2) #S(SYSTEM::GESTURE-SPEC :DATA 71 :MODIFIERS 2)) :STYLE :EMACS :POINT-ALWAYS-VISIBLE T :USE-FACE-TO-FULL-WIDTH-P T)
Binding frame:
CAPI::*USE-ACCELERATORS* : T
Binding frame:
CAPI-WIN32-LIB::*ALT-IS-META-KEY* : T
Catch frame: #:|progv-cathcer236969|
Call to MP::PROCESS-SG-FUNCTION (offset 509)
MP::STACK-ARG : NIL
MP::SYMBOLS : NIL
VALUES : NIL
Catch frame: SYSTEM::EXIT-FOREIGN-CALLABLE
Call to SYSTEM::FOREIGN-CALLABLE-ENTRY-POINT-NEW-PROCESS (offset 173)
SYSTEM::FUNC : SYSTEM::|%FOREIGN-CALLABLE/lisp_signal_error_on_c_stack|
Call to SYSTEM::%FUNCALL1-ON-LISP-STACK (offset 34)
SYSTEM::%FUNCALL1-ON-LISP-STACK
T
CL-USER 3 : 1 >
--- end of long backtrace ---