[Openmcl-devel] RDNZL in CCL: Exception occurred while executing foreign code

John Miller millejoh at mac.com
Fri Oct 16 21:28:51 UTC 2009


Again, ample evidence that I should not quit my day job any time soon  
and stride boldy into the world of software development.  I would  
probably trip and break my nose in the fall.

The problem looks to be one of passing the wrong type of argument.   
The C function I am calling is defined as

void* invokeInstanceMember(const __wchar_t *methodName, void *target,  
int nargs, void *args[])

h-to-ffi.sh interprets that to be

(function ("/cygdrive/d/rdnzl-cpp-0.7.1/RDNZL/ffi-headers.h" 55)
  "invokeInstanceMember"
  (function
   ((pointer (unsigned-short ())) (pointer (void ())) (int ())  
(pointer (pointer (void ()))) )
   (pointer (void ()))) (extern))

Then, given the following definitions:

(defun %invoke-instance-member (method-name type nargs args)
   (ccl::with-native-utf-16-cstr (mn method-name)
     (#_invokeInstanceMember mn type nargs args)))

(defun test-invoke-2 ()
   (let ((obj (make-type-from-name "System.Reflection.Assembly")))
     (%invoke-instance-member "ToString" (pointer obj) 0 (ccl:%null- 
ptr))))

(defun test-invoke-3 ()
   (let ((obj (make-type-from-name "System.Reflection.Assembly"))
	(type (box* "System.Reflection.Assembly")))
     (ccl:rletz ((ptr (:array :address 1)))
       (setf (ccl:paref ptr (:array :address) 0) type)
       (%invoke-instance-member "GetType" (pointer obj) 1 ptr))))

I call (test-invoke-2) and all is hunky-dorey, but I try (test- 
invoke-3) and all heck breaks loose.  I have imagined, and tried a  
couple different ways of representing an array of pointers, but  
clearly I am not imaginative enough.

It would be interesting to know if anyone else has tried calling  
foreign functions that have arguments of type void *args[].  I mean  
other than the code in cocoa-ide/start.lisp that I based the code in  
test-invoke-3 off of.

Cheers,
John


(unwind-protect
On Oct 12, 2009, at 3:51 PM, Gary Byers wrote:

> 'exception' in this context almost certainly means machine-level  
> exception
> (e.g., attempt to reference memory that isn't there, attempt to  
> execute
> an illegal instruction ...) and doesn't likely refer to a C++ runtime
> exception.
>
> Beyond the fact that it can show a backtrace of the lisp stack leading
> up to the ff-call, CCL's kernel debugger isn't very useful for  
> debugging
> exceptions that occur in foreign (C, C++) code.  There are some  
> (somewhat
> Unix-centric) notes on using GDB at:
>
> <http://trac.clozure.com/openmcl/wiki/CclUnderGdb>
>
> Native Windows debuggers may work better for debugging crashes that  
> occur
> in Windows dlls; it's been a long time since I've tried to run CCL  
> under
> something like WinDbg, and I don't remember whether there were  
> issues or
> what they were.
>
> I suppose that there are other possibilities, but I'd be most  
> suspicious
> of the FFI/CFFI code: passing the wrong number/types of arguments to a
> C[++] function can certainly lead to a memory fault or other type of
> machine exception.
>
> [It varies a bit by platform, but CCL isn't always consistent about  
> telling
> you what general kind of machine exception occurred when that  
> exception
> occurred in foreign code; on OSX, trying to FF-CALL a null pointer  
> enters
> the kernel debugger with a (very) slightly more informative message:
>
> ? (ff-call (%null-ptr) :void)
> Unhandled exception 10 at 0x0, context->regs at #xb029b8f0
> Exception occurred while executing foreign code
> ? for help
> [2086] Clozure CL kernel debugger:
>
> The "unhandled exception 10" means "bus error" (SIGBUS = 10), which is
> at least a little better than saying nothing in this case.]
>
> On Mon, 12 Oct 2009, John Miller wrote:
>
>> All,
>>
>> On a wild hair, it seemed like it might be useful to have CCL  
>> running on my Windows XP 32-bit machine at work and use it to  
>> access Excel and Outlook using Dr. Edi Weitz's RDNZL (http://weitz.de/rdnzl/ 
>> ) package.  Doing this has turned out to be more difficult than I  
>> thought.  I built the FFI portion of the code using CFFI to look as  
>> close as possible to the FFI interfaces defined for the other lisps.
>>
>> For some things the FFI works.  For example:
>>
>> ? (make-type-from-name "System.Reflection.Assembly")
>> #<CONTAINER System.Type #x1532E08>
>> ? (import-assembly "mscorlib")
>> #<CONTAINER System.Reflection.Assembly #x1532EA8>
>>
>> But if I try to get fancy:
>>
>> ? (import-types "System.Windows.Forms" "MessageBox")
>> %eax = 0x00faf00c
>> %ecx = 0x00000000
>> %edx = 0x00000002
>> %ebx = 0x79f7697c
>> %esp = 0x00faf008
>> %ebp = 0x00faf05c
>> %esi = 0x00faf094
>> %edi = 0x0040a958
>> %eip = 0x7c812a6b
>> %eflags = 0x00000206
>>
>> %cs = 0x001b
>> %ds = 0x0023
>> %ss = 0x0023
>> %es = 0x0023
>> %fs = 0x003b
>> %gs = 0x0000
>> Exception on foreign stack
>>
>> Exception occurred while executing foreign code
>> ? for help
>> [2068] Clozure CL kernel debugger: t
>> Current Thread Context Record (tcr) = 0x5cbc20
>> Control (C) stack area:  low = 0xdb0000, high = 0xfb0000
>> Value (lisp) stack area: low = 0xfb0000, high = 0x0
>> Exception stack pointer = 0xfaf008
>> [2068] Clozure CL kernel debugger: b
>> current thread: tcr = 0x5cbc20, native thread ID = 0xde4,  
>> interrupts enabled
>>
>>
>> (#x010C0CD0) #x08D52435 : #<Function %INVOKE-STATIC-MEMBER  
>> #x08D52266> + 463
>> (#x010C0D14) #x08D794D5 : #<Function INVOKE #x08D7854E> + 3975
>> (#x010C0D78) #x08DD281D : #<Function IMPORT-TYPES #x08DD27CE> + 79
>> (#x010C0D88) #x0839E9BD : #<Function CALL-CHECK-REGS #x0839E8C6> +  
>> 247
>> (#x010C0DA4) #x083A8FE5 : #<Function TOPLEVEL-EVAL #x083A8CFE> + 743
>> (#x010C0DE8) #x083AAA35 : #<Function READ-LOOP #x083AA30E> + 1831
>> (#x010C0EFC) #x0839E60D : #<Function TOPLEVEL-LOOP #x0839E5C6> + 71
>> (#x010C0F04) #x0834222D : #<Function (:INTERNAL (TOPLEVEL-FUNCTION  
>> (LISP-DEVELOP
>> MENT-SYSTEM T))) #x083421CE> + 95
>> (#x010C0F14) #x0840FDED : #<Function (:INTERNAL MAKE-MCL-LISTENER- 
>> PROCESS) #x08$
>> 0FBA6> + 583
>> (#x010C0F60) #x083484DD : #<Function RUN-PROCESS-INITIAL-FORM  
>> #x0834823E> + 671
>> (#x010C0FA4) #x08348E7D : #<Function (:INTERNAL (%PROCESS-PRESET- 
>> INTERNAL (PROCE
>> SS))) #x08348D2E> + 335
>> (#x010C0FCC) #x083317A5 : #<Function (:INTERNAL THREAD-MAKE-STARTUP- 
>> FUNCTION) #x
>> 0833168E> + 279
>> [2068] Clozure CL kernel debugger:
>>
>> Note that I can get RDNZL to work fine using CLISP 2.48 on this  
>> same machine.
>>
>> I believe part of the problem with CCL is that Edi's C++ code will  
>> throw a C++ exception under certain conditions (though I can't  
>> figure out why the above call to %invoke-static-member is causing  
>> an exception).  Other Lisp's seem to handle this without going into  
>> the kernel debugger.  For example with Clisp 2.48 running on the  
>> same machine
>>
>> RDNZL[36]> (property "System.Reflection.Assembly" "FullName")
>>
>> *** - .NET error (System.Exception): Static property not found:
>>      System.Reflection.Assembly->FullName
>>
>> Trying to call property with the same arguments in CCL bumps me  
>> into the kernel debugger.  Again, I am not 100% convinced this is  
>> the problem, but I am not sure how to interpret the output from the  
>> debugger and come up with a better hypothesis of what is happening.
>>
>> Best regards,
>> John Miller
>> _______________________________________________
>> Openmcl-devel mailing list
>> Openmcl-devel at clozure.com
>> http://clozure.com/mailman/listinfo/openmcl-devel
>>
>>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.clozure.com/pipermail/openmcl-devel/attachments/20091016/a785be4d/attachment.html>


More information about the Openmcl-devel mailing list