Ticket #261 (closed defect: wontfix)
circular contracts cause mono to segfault
Reported by: | blubb | Owned by: | Chuck |
---|---|---|---|
Priority: | major | Milestone: | |
Component: | Cobra Compiler | Version: | 0.8.0 |
Keywords: | Cc: |
Description
the following code causes mono to crash with a SIGSEGV:
class Oops def oneMore as int ensure result == .oneLess + 1 body print "oneMore executed" return 3 def oneLess as int ensure result == .oneMore - 1 body print "oneLess executed" return 2 def main .oneMore
Output:
$ ./oops.exe oneMore executed oneLess executed oneMore executed oneLess executed oneMore executed [... ~15'000 of these ...] Stacktrace: Native stacktrace: /usr/bin/cli() [0x47b77f] /usr/bin/cli() [0x4aef3f] /lib/libpthread.so.0(+0xfb40) [0x7f3912fc0b40] /usr/bin/cli() [0x4aee86] /lib/libpthread.so.0(+0xfb40) [0x7f3912fc0b40] [0x402cd7c7] Debug info from gdb: 82 ../sysdeps/unix/syscall-template.S: No such file or directory. Cannot access memory at address 0x7fffe72a3f80 [Thread debugging using libthread_db enabled] [New Thread 0x7f39118a1710 (LWP 15767)] [New Thread 0x7f3913b0e710 (LWP 15766)] 0x00007f3912fbfb8d in read () at ../sysdeps/unix/syscall-template.S:82 in ../sysdeps/unix/syscall-template.S 3 Thread 0x7f3913b0e710 (LWP 15766) 0x00007f3912fc036d in nanosleep () at ../sysdeps/unix/syscall-template.S:82 2 Thread 0x7f39118a1710 (LWP 15767) sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86 * 1 Thread 0x7f3913cb8740 (LWP 15764) 0x00007f3912fbfb8d in read () at ../sysdeps/unix/syscall-template.S:82 Thread 3 (Thread 0x7f3913b0e710 (LWP 15766)): #0 0x00007f3912fc036d in nanosleep () at ../sysdeps/unix/syscall-template.S:82 #1 0x0000000000556342 in ?? () #2 0x00007f3912fb8971 in start_thread (arg=<value optimized out>) at pthread_create.c:304 #3 0x00007f3912a9191d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112 #4 0x0000000000000000 in ?? () Thread 2 (Thread 0x7f39118a1710 (LWP 15767)): #0 sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86 #1 0x00000000004e4aaa in ?? () #2 0x0000000000505035 in ?? () #3 0x0000000000570073 in ?? () #4 0x000000000058de21 in ?? () #5 0x00007f3912fb8971 in start_thread (arg=<value optimized out>) at pthread_create.c:304 #6 0x00007f3912a9191d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112 #7 0x0000000000000000 in ?? () Thread 1 (Thread 0x7f3913cb8740 (LWP 15764)): #0 0x00007f3912fbfb8d in read () at ../sysdeps/unix/syscall-template.S:82 #1 0x000000000047b8f4 in ?? () #2 0x00000000004aef3f in ?? () #3 <signal handler called> #4 0x00000000004aee86 in ?? () #5 <signal handler called> #6 0x00000000402cd7c7 in ?? () ================================================================= Got a SIGSEGV while executing native code. This usually indicates a fatal error in the mono runtime or one of the native libraries used by your application. =================================================================
There are several options to deal with contracts that circularly reference themselves:
- detect and warn at compile-time
- detect and report error at compile-time
- when executing contracts, do not go deeper than <arbitraryNumber> stack frames. when the limit is exceeded, just assume the contract to be fulfilled. (this is what Eiffel does)
Either way, the larger programs become, the harder it is to write contracts that do not contain circles in their dependency graph. In my experience (<rant>as a student of Bertrand Meyer, who was forced to write LOTS of contracts</rant>), as soon as you started thinking about what contracts you may use where, contracts turn from a useful feature into nuisances. Also, implementing the solution Eiffel uses will really piss people off. After all, if they specify contracts, they expect them to fail if a condition is not met.
Change History
Note: See
TracTickets for help on using
tickets.