Marc,
I got a sigsegv. I suspect it's because some FFI got a failed malloc() maybe, that the Scheme code then not handled as it should.
Or it could be some FFI-related heap corruption (basically all Scheme code is safe so shouldn't cause any of that).
Gambit in itself is 100% malloc-failure-safe right, so there is not one single instance when Gambit code actually would
Also maybe it could be how I pass values between C and Scheme, that something is broken somewhere there - what did the introduction of the ___return() macro really resolve??
I just wanted to ask you to have a quick look at the GDB output below, to give your thought on what would be more and less plausible sources of this error.
Finally, in an environment where you want to maximize reliability, would there be some way to add extra heap corruption checks??
As to be able to understand where the corruption actually happened - i mean what we get here is just a code pointer into the Gambit VM code, it's completely un-instructive.
You know like that GCC patch that pads the stack with extra bytes and then checks, StackGuard or whatever it's called.
I guess in the case of my crash here below, the actual problem is that someone overwrote the stack frame right?
Thanks!!
(gdb) thread apply all bt
Thread 1 (process 16563): #0 0x00000c4a6fb10905 in ___H__20___kernel (_(short *)=0xc4a707222a0 <___gstate>) at _kernel.c:4358 Backtrace stopped: Cannot access memory at address 0x7f7ffffd1028
that line is:
/* setup internal return continuation frame */
ra = ___ps->temp1;
___RETI_GET_CFS(ra,fs) <- this one!
___ADJFP(___ROUND_TO_MULT(fs,___FRAME_ALIGN)-fs)
___PUSH_REGS /* push all GVM registers (live or not) */ ___PUSH(ra) /* push return address */
and then additionally:
(gdb) info locals descr = 13524638833968 fs = <optimized out> ra = 13524639556321 ___r4 = <optimized out> ___r1 = 0 ___hlbltbl = {0x0, 0x40fbe4, 0x40fcdf, 0x4172d2, 0x40fd2a, 0x41248a, 0x40fdcc, 0x40fe13, 0x40fe2e, 0x41eb0c, 0x40feb9, 0x40ff2a, 0x40ff73, 0x40ff9b, 0x40ffba, 0x40ffd9, 0x40fff8, 0x410017, 0x410036, 0x410055, 0x4101b3, 0x4105af, 0x4105db, 0x41066f, 0x410678, 0x4106ca, 0x41073e, 0x0, 0x41075a, 0x4107f1, 0x4108ef, 0x410adc, 0x410b7d, 0x410c85, 0x410d98, 0x410ec3, 0x41123c, 0x4116a0, 0x411cb1, 0x411d9e, 0x411e5c, 0x4120dc, 0x0, 0x41214e, 0x412211, 0x0, 0x412269, 0x0, 0x4122e0, 0x0, 0x412357, 0x0, 0x412425, 0x0, 0x4124b9, 0x0, 0x412542, 0x415d4e, 0x0, 0x4125f7, 0x0, 0x4126a2, 0x412716, 0x4127cd, 0x0, 0x412802, 0x4128bf, 0x0, 0x4128c4, 0x0, 0x41296f, 0x4129d7, 0x412a8e, 0x0, 0x412ac3, 0x412b80, 0x0, 0x412b85, 0x0, 0x412c30, 0x412d09, 0x0, 0x412d30, 0x412e09, 0x0, 0x412e30, 0x412f09, 0x0, 0x412f30, 0x413009, 0x0, 0x413030, 0x0, 0x4130a0, 0x0, 0x4130fc, 0x0, 0x413192, 0x41328a, 0x4132d3, 0x0, 0x41330c, 0x4133c9, 0x0, 0x4133ce, 0x0, 0x413479, 0x413552, 0x0, 0x413579, 0x413652, 0x0, 0x413679, 0x0, 0x4136d5, 0x4137bb, 0x413804, 0x0, 0x413839, 0x4138f6, 0x0, 0x4138fb, 0x0, 0x4139a6, 0x413a7f, 0x0, 0x413aa6, 0x413b7f, 0x0, 0x413ba6, 0x0, 0x413c02, 0x413ce8, 0x413d31, 0x0, 0x413d66, 0x413e23, 0x0, 0x413e28, 0x0, 0x413ed3, 0x413fac, 0x0, 0x413fd3, 0x4140ac, 0x0, 0x4140d3, 0x0, 0x41412f, 0x414215, 0x41425e, 0x0, 0x414293, 0x414350, 0x0, 0x414355, 0x0, 0x414400, 0x4144d9, 0x0, 0x414500, 0x4145d9, 0x0, 0x414600, 0x4146d9, 0x0, 0x414700, 0x4147d9, 0x0, 0x414800, 0x41490b, 0x414954, 0x0, 0x41498d, 0x414a4a, 0x0, 0x414a4f, 0x0, 0x414afa, 0x414bd3, 0x0, 0x414bfa, 0x414cd3, 0x0, 0x414cfa, 0x414dd3, 0x0, 0x414dfa, 0x414ed3, 0x0, 0x414efa, 0x414fe9, 0x415032, 0x0, 0x415067, 0x415124, 0x0, 0x415129, 0x0, 0x4151d4...} _(char *) = <optimized out> ___temp = <optimized out> ___hp = <error reading variable ___hp (Cannot access memory at address 0x7f7ffffcefa0)> _(float, *) = 0xc4d48ab94c0 _(long double, ) = <error reading variable _(long double, ) (Cannot access memory at address 0x7f7ffffcef68)> ___r2 = 13524703568041 ___start = <optimized out> ___r3 = <error reading variable ___r3 (Cannot access memory at address 0x7f7ffffcef60)> (gdb) info args _(short *) = 0xc4a707222a0 <___gstate>
Afficher les réponses par date
Umm - or - more specifically, what happened here is some level of heap corruption, and question is what caused it.
I guess it should be some C code (i.e. FFI), either the C code itself or directly or indirectly broken values primarily passed from C to Scheme, and that in turn could happen either because I pass return values incorrectly or because of some unexpected code path like malloc leading to broken C code execution somewhere.
The bug appears however at first where the GVM crashes because of trying to operate on the broken heap content, which happened to be a stack frame. So any way to extract information about which the most recent line of Scheme code executed would help here.
Even if the GVM implemented two local variables would help - containing the module name and line of code, that was most recently executed. (Or the last 3.)
This would probably work because the heap is still so intact that GDB's "info variables" works.
Would this be difficult to implement?
Thanks :D
2016-01-20 15:27 GMT+08:00 Adam adam.mlmb@gmail.com:
Marc,
I got a sigsegv. I suspect it's because some FFI got a failed malloc() maybe, that the Scheme code then not handled as it should.
Or it could be some FFI-related heap corruption (basically all Scheme code is safe so shouldn't cause any of that).
Gambit in itself is 100% malloc-failure-safe right, so there is not one single instance when Gambit code actually would
Also maybe it could be how I pass values between C and Scheme, that something is broken somewhere there - what did the introduction of the ___return() macro really resolve??
I just wanted to ask you to have a quick look at the GDB output below, to give your thought on what would be more and less plausible sources of this error.
Finally, in an environment where you want to maximize reliability, would there be some way to add extra heap corruption checks??
As to be able to understand where the corruption actually happened - i mean what we get here is just a code pointer into the Gambit VM code, it's completely un-instructive.
You know like that GCC patch that pads the stack with extra bytes and then checks, StackGuard or whatever it's called.
I guess in the case of my crash here below, the actual problem is that someone overwrote the stack frame right?
Thanks!!
(gdb) thread apply all bt
Thread 1 (process 16563): #0 0x00000c4a6fb10905 in ___H__20___kernel (_(short *)=0xc4a707222a0 <___gstate>) at _kernel.c:4358 Backtrace stopped: Cannot access memory at address 0x7f7ffffd1028
that line is:
/* setup internal return continuation frame */
ra = ___ps->temp1;
___RETI_GET_CFS(ra,fs) <- this one!
___ADJFP(___ROUND_TO_MULT(fs,___FRAME_ALIGN)-fs)
___PUSH_REGS /* push all GVM registers (live or not) */ ___PUSH(ra) /* push return address */
and then additionally:
(gdb) info locals descr = 13524638833968 fs = <optimized out> ra = 13524639556321 ___r4 = <optimized out> ___r1 = 0 ___hlbltbl = {0x0, 0x40fbe4, 0x40fcdf, 0x4172d2, 0x40fd2a, 0x41248a, 0x40fdcc, 0x40fe13, 0x40fe2e, 0x41eb0c, 0x40feb9, 0x40ff2a, 0x40ff73, 0x40ff9b, 0x40ffba, 0x40ffd9, 0x40fff8, 0x410017, 0x410036, 0x410055, 0x4101b3, 0x4105af, 0x4105db, 0x41066f, 0x410678, 0x4106ca, 0x41073e, 0x0, 0x41075a, 0x4107f1, 0x4108ef, 0x410adc, 0x410b7d, 0x410c85, 0x410d98, 0x410ec3, 0x41123c, 0x4116a0, 0x411cb1, 0x411d9e, 0x411e5c, 0x4120dc, 0x0, 0x41214e, 0x412211, 0x0, 0x412269, 0x0, 0x4122e0, 0x0, 0x412357, 0x0, 0x412425, 0x0, 0x4124b9, 0x0, 0x412542, 0x415d4e, 0x0, 0x4125f7, 0x0, 0x4126a2, 0x412716, 0x4127cd, 0x0, 0x412802, 0x4128bf, 0x0, 0x4128c4, 0x0, 0x41296f, 0x4129d7, 0x412a8e, 0x0, 0x412ac3, 0x412b80, 0x0, 0x412b85, 0x0, 0x412c30, 0x412d09, 0x0, 0x412d30, 0x412e09, 0x0, 0x412e30, 0x412f09, 0x0, 0x412f30, 0x413009, 0x0, 0x413030, 0x0, 0x4130a0, 0x0, 0x4130fc, 0x0, 0x413192, 0x41328a, 0x4132d3, 0x0, 0x41330c, 0x4133c9, 0x0, 0x4133ce, 0x0, 0x413479, 0x413552, 0x0, 0x413579, 0x413652, 0x0, 0x413679, 0x0, 0x4136d5, 0x4137bb, 0x413804, 0x0, 0x413839, 0x4138f6, 0x0, 0x4138fb, 0x0, 0x4139a6, 0x413a7f, 0x0, 0x413aa6, 0x413b7f, 0x0, 0x413ba6, 0x0, 0x413c02, 0x413ce8, 0x413d31, 0x0, 0x413d66, 0x413e23, 0x0, 0x413e28, 0x0, 0x413ed3, 0x413fac, 0x0, 0x413fd3, 0x4140ac, 0x0, 0x4140d3, 0x0, 0x41412f, 0x414215, 0x41425e, 0x0, 0x414293, 0x414350, 0x0, 0x414355, 0x0, 0x414400, 0x4144d9, 0x0, 0x414500, 0x4145d9, 0x0, 0x414600, 0x4146d9, 0x0, 0x414700, 0x4147d9, 0x0, 0x414800, 0x41490b, 0x414954, 0x0, 0x41498d, 0x414a4a, 0x0, 0x414a4f, 0x0, 0x414afa, 0x414bd3, 0x0, 0x414bfa, 0x414cd3, 0x0, 0x414cfa, 0x414dd3, 0x0, 0x414dfa, 0x414ed3, 0x0, 0x414efa, 0x414fe9, 0x415032, 0x0, 0x415067, 0x415124, 0x0, 0x415129, 0x0, 0x4151d4...} _(char *) = <optimized out> ___temp = <optimized out> ___hp = <error reading variable ___hp (Cannot access memory at address 0x7f7ffffcefa0)> _(float, *) = 0xc4d48ab94c0 _(long double, ) = <error reading variable _(long double, ) (Cannot access memory at address 0x7f7ffffcef68)> ___r2 = 13524703568041 ___start = <optimized out> ___r3 = <error reading variable ___r3 (Cannot access memory at address 0x7f7ffffcef60)> (gdb) info args _(short *) = 0xc4a707222a0 <___gstate>
Marc,
Made an issue with this as a feature request:
https://github.com/feeley/gambit/issues/172
Would this be very easy to implement?
An untrackable SIGSEGV is really a nightmare of sorts so your attention to this request for debug feature that remedies it would be very much appreciated!
2016-01-20 15:31 GMT+08:00 Adam adam.mlmb@gmail.com:
Umm - or - more specifically, what happened here is some level of heap corruption, and question is what caused it.
I guess it should be some C code (i.e. FFI), either the C code itself or directly or indirectly broken values primarily passed from C to Scheme, and that in turn could happen either because I pass return values incorrectly or because of some unexpected code path like malloc leading to broken C code execution somewhere.
The bug appears however at first where the GVM crashes because of trying to operate on the broken heap content, which happened to be a stack frame. So any way to extract information about which the most recent line of Scheme code executed would help here.
Even if the GVM implemented two local variables would help - containing the module name and line of code, that was most recently executed. (Or the last 3.)
This would probably work because the heap is still so intact that GDB's "info variables" works.
Would this be difficult to implement?
Thanks :D
2016-01-20 15:27 GMT+08:00 Adam adam.mlmb@gmail.com:
Marc,
I got a sigsegv. I suspect it's because some FFI got a failed malloc() maybe, that the Scheme code then not handled as it should.
Or it could be some FFI-related heap corruption (basically all Scheme code is safe so shouldn't cause any of that).
Gambit in itself is 100% malloc-failure-safe right, so there is not one single instance when Gambit code actually would
Also maybe it could be how I pass values between C and Scheme, that something is broken somewhere there - what did the introduction of the ___return() macro really resolve??
I just wanted to ask you to have a quick look at the GDB output below, to give your thought on what would be more and less plausible sources of this error.
Finally, in an environment where you want to maximize reliability, would there be some way to add extra heap corruption checks??
As to be able to understand where the corruption actually happened - i mean what we get here is just a code pointer into the Gambit VM code, it's completely un-instructive.
You know like that GCC patch that pads the stack with extra bytes and then checks, StackGuard or whatever it's called.
I guess in the case of my crash here below, the actual problem is that someone overwrote the stack frame right?
Thanks!!
(gdb) thread apply all bt
Thread 1 (process 16563): #0 0x00000c4a6fb10905 in ___H__20___kernel (_(short *)=0xc4a707222a0 <___gstate>) at _kernel.c:4358 Backtrace stopped: Cannot access memory at address 0x7f7ffffd1028
that line is:
/* setup internal return continuation frame */
ra = ___ps->temp1;
___RETI_GET_CFS(ra,fs) <- this one!
___ADJFP(___ROUND_TO_MULT(fs,___FRAME_ALIGN)-fs)
___PUSH_REGS /* push all GVM registers (live or not) */ ___PUSH(ra) /* push return address */
and then additionally:
(gdb) info locals descr = 13524638833968 fs = <optimized out> ra = 13524639556321 ___r4 = <optimized out> ___r1 = 0 ___hlbltbl = {0x0, 0x40fbe4, 0x40fcdf, 0x4172d2, 0x40fd2a, 0x41248a, 0x40fdcc, 0x40fe13, 0x40fe2e, 0x41eb0c, 0x40feb9, 0x40ff2a, 0x40ff73, 0x40ff9b, 0x40ffba, 0x40ffd9, 0x40fff8, 0x410017, 0x410036, 0x410055, 0x4101b3, 0x4105af, 0x4105db, 0x41066f, 0x410678, 0x4106ca, 0x41073e, 0x0, 0x41075a, 0x4107f1, 0x4108ef, 0x410adc, 0x410b7d, 0x410c85, 0x410d98, 0x410ec3, 0x41123c, 0x4116a0, 0x411cb1, 0x411d9e, 0x411e5c, 0x4120dc, 0x0, 0x41214e, 0x412211, 0x0, 0x412269, 0x0, 0x4122e0, 0x0, 0x412357, 0x0, 0x412425, 0x0, 0x4124b9, 0x0, 0x412542, 0x415d4e, 0x0, 0x4125f7, 0x0, 0x4126a2, 0x412716, 0x4127cd, 0x0, 0x412802, 0x4128bf, 0x0, 0x4128c4, 0x0, 0x41296f, 0x4129d7, 0x412a8e, 0x0, 0x412ac3, 0x412b80, 0x0, 0x412b85, 0x0, 0x412c30, 0x412d09, 0x0, 0x412d30, 0x412e09, 0x0, 0x412e30, 0x412f09, 0x0, 0x412f30, 0x413009, 0x0, 0x413030, 0x0, 0x4130a0, 0x0, 0x4130fc, 0x0, 0x413192, 0x41328a, 0x4132d3, 0x0, 0x41330c, 0x4133c9, 0x0, 0x4133ce, 0x0, 0x413479, 0x413552, 0x0, 0x413579, 0x413652, 0x0, 0x413679, 0x0, 0x4136d5, 0x4137bb, 0x413804, 0x0, 0x413839, 0x4138f6, 0x0, 0x4138fb, 0x0, 0x4139a6, 0x413a7f, 0x0, 0x413aa6, 0x413b7f, 0x0, 0x413ba6, 0x0, 0x413c02, 0x413ce8, 0x413d31, 0x0, 0x413d66, 0x413e23, 0x0, 0x413e28, 0x0, 0x413ed3, 0x413fac, 0x0, 0x413fd3, 0x4140ac, 0x0, 0x4140d3, 0x0, 0x41412f, 0x414215, 0x41425e, 0x0, 0x414293, 0x414350, 0x0, 0x414355, 0x0, 0x414400, 0x4144d9, 0x0, 0x414500, 0x4145d9, 0x0, 0x414600, 0x4146d9, 0x0, 0x414700, 0x4147d9, 0x0, 0x414800, 0x41490b, 0x414954, 0x0, 0x41498d, 0x414a4a, 0x0, 0x414a4f, 0x0, 0x414afa, 0x414bd3, 0x0, 0x414bfa, 0x414cd3, 0x0, 0x414cfa, 0x414dd3, 0x0, 0x414dfa, 0x414ed3, 0x0, 0x414efa, 0x414fe9, 0x415032, 0x0, 0x415067, 0x415124, 0x0, 0x415129, 0x0, 0x4151d4...} _(char *) = <optimized out> ___temp = <optimized out> ___hp = <error reading variable ___hp (Cannot access memory at address 0x7f7ffffcefa0)> _(float, *) = 0xc4d48ab94c0 _(long double, ) = <error reading variable _(long double, ) (Cannot access memory at address 0x7f7ffffcef68)> ___r2 = 13524703568041 ___start = <optimized out> ___r3 = <error reading variable ___r3 (Cannot access memory at address 0x7f7ffffcef60)> (gdb) info args _(short *) = 0xc4a707222a0 <___gstate>