GNU bug report logs - #13074
VM Segfaults with Bad `Call' Instruction

Previous Next

Package: guile;

Reported by: Noah Lavine <noah.b.lavine <at> gmail.com>

Date: Tue, 4 Dec 2012 03:10:02 UTC

Severity: normal

Done: ludo <at> gnu.org (Ludovic Courtès)

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 13074 in the body.
You can then email your comments to 13074 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guile <at> gnu.org:
bug#13074; Package guile. (Tue, 04 Dec 2012 03:10:03 GMT) Full text and rfc822 format available.

Acknowledgement sent to Noah Lavine <noah.b.lavine <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-guile <at> gnu.org. (Tue, 04 Dec 2012 03:10:03 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Noah Lavine <noah.b.lavine <at> gmail.com>
To: bug-guile <at> gnu.org
Subject: VM Segfaults with Bad `Call' Instruction
Date: Mon, 3 Dec 2012 22:06:28 -0500
[Message part 1 (text/plain, inline)]
Hello,

This is an interesting bug, because the only way to hit it (as far as I can
tell) is to mess up when writing a compiler. However, I did mess up, and I
discover that I can generate a `call' instruction in the trunk VM where the
procedure to call will be 0x0. Then the VM will try to check whether the
procedure is really a procedure, and Guile will segfault at line 796 of
v-i-system.c.

I think the correct behavior would be to throw a `vm-bad-instruction' error
instead. The fix should be pretty simple - just check if program is 0x0 and
jump to vm-bad-instruction in that case.

Noah
[Message part 2 (text/html, inline)]

Information forwarded to bug-guile <at> gnu.org:
bug#13074; Package guile. (Wed, 05 Dec 2012 03:28:02 GMT) Full text and rfc822 format available.

Message #8 received at 13074 <at> debbugs.gnu.org (full text, mbox):

From: Noah Lavine <noah.b.lavine <at> gmail.com>
To: 13074 <at> debbugs.gnu.org
Subject: Re: bug#13074: VM Segfaults with Bad `Call' Instruction
Date: Tue, 4 Dec 2012 22:26:52 -0500
[Message part 1 (text/plain, inline)]
The following patch fixes the problem for me:

diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c
index 7153ab5..dff2ab2 100644
--- a/libguile/vm-i-system.c
+++ b/libguile/vm-i-system.c
@@ -793,7 +793,9 @@ VM_DEFINE_INSTRUCTION (55, call, "call", 1, -1, 1)

   VM_HANDLE_INTERRUPTS;

-  if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
+  if (SCM_UNLIKELY (program == NULL))
+    goto vm_error_bad_instruction;
+  else if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
     {
       if (SCM_STRUCTP (program) && SCM_STRUCT_APPLICABLE_P (program))
         {

Any objections if I apply it to stable-2.0? (Or master?)

Noah


On Mon, Dec 3, 2012 at 10:06 PM, Noah Lavine <noah.b.lavine <at> gmail.com>wrote:

> Hello,
>
> This is an interesting bug, because the only way to hit it (as far as I
> can tell) is to mess up when writing a compiler. However, I did mess up,
> and I discover that I can generate a `call' instruction in the trunk VM
> where the procedure to call will be 0x0. Then the VM will try to check
> whether the procedure is really a procedure, and Guile will segfault at
> line 796 of v-i-system.c.
>
> I think the correct behavior would be to throw a `vm-bad-instruction'
> error instead. The fix should be pretty simple - just check if program is
> 0x0 and jump to vm-bad-instruction in that case.
>
> Noah
>
>
[Message part 2 (text/html, inline)]

Information forwarded to bug-guile <at> gnu.org:
bug#13074; Package guile. (Wed, 05 Dec 2012 14:11:01 GMT) Full text and rfc822 format available.

Message #11 received at 13074 <at> debbugs.gnu.org (full text, mbox):

From: ludo <at> gnu.org (Ludovic Courtès)
To: Noah Lavine <noah.b.lavine <at> gmail.com>
Cc: 13074 <at> debbugs.gnu.org
Subject: Re: bug#13074: VM Segfaults with Bad `Call' Instruction
Date: Wed, 05 Dec 2012 15:10:10 +0100
Hi Noah,

Noah Lavine <noah.b.lavine <at> gmail.com> skribis:

> diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c
> index 7153ab5..dff2ab2 100644
> --- a/libguile/vm-i-system.c
> +++ b/libguile/vm-i-system.c
> @@ -793,7 +793,9 @@ VM_DEFINE_INSTRUCTION (55, call, "call", 1, -1, 1)
>
>    VM_HANDLE_INTERRUPTS;
>
> -  if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
> +  if (SCM_UNLIKELY (program == NULL))
> +    goto vm_error_bad_instruction;
> +  else if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
>      {
>        if (SCM_STRUCTP (program) && SCM_STRUCT_APPLICABLE_P (program))
>          {

I’d rather not apply it, because it adds overhead for every call for a
situation that cannot happen when using Guile’s compiler, IIUC.

WDYT?

Thanks,
Ludo’.




Information forwarded to bug-guile <at> gnu.org:
bug#13074; Package guile. (Wed, 05 Dec 2012 14:55:01 GMT) Full text and rfc822 format available.

Message #14 received at 13074 <at> debbugs.gnu.org (full text, mbox):

From: Noah Lavine <noah.b.lavine <at> gmail.com>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 13074 <at> debbugs.gnu.org
Subject: Re: bug#13074: VM Segfaults with Bad `Call' Instruction
Date: Wed, 5 Dec 2012 09:54:20 -0500
[Message part 1 (text/plain, inline)]
That makes sense. I hit this error in debugging a CPS->GLIL compiler (which
I hope will become Guile's compiler, but that's another story). However,
once the debugging is done, I suppose it won't make a difference.

What do you think about enabling it only in the debug VM, or something like
that? Then if there's some way for me to run my code in debug mode, I can
get the better output without slowing down most things.

Noah


On Wed, Dec 5, 2012 at 9:10 AM, Ludovic Courtès <ludo <at> gnu.org> wrote:

> Hi Noah,
>
> Noah Lavine <noah.b.lavine <at> gmail.com> skribis:
>
> > diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c
> > index 7153ab5..dff2ab2 100644
> > --- a/libguile/vm-i-system.c
> > +++ b/libguile/vm-i-system.c
> > @@ -793,7 +793,9 @@ VM_DEFINE_INSTRUCTION (55, call, "call", 1, -1, 1)
> >
> >    VM_HANDLE_INTERRUPTS;
> >
> > -  if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
> > +  if (SCM_UNLIKELY (program == NULL))
> > +    goto vm_error_bad_instruction;
> > +  else if (SCM_UNLIKELY (!SCM_PROGRAM_P (program)))
> >      {
> >        if (SCM_STRUCTP (program) && SCM_STRUCT_APPLICABLE_P (program))
> >          {
>
> I’d rather not apply it, because it adds overhead for every call for a
> situation that cannot happen when using Guile’s compiler, IIUC.
>
> WDYT?
>
> Thanks,
> Ludo’.
>
[Message part 2 (text/html, inline)]

Information forwarded to bug-guile <at> gnu.org:
bug#13074; Package guile. (Wed, 05 Dec 2012 22:15:01 GMT) Full text and rfc822 format available.

Message #17 received at 13074 <at> debbugs.gnu.org (full text, mbox):

From: ludo <at> gnu.org (Ludovic Courtès)
To: Noah Lavine <noah.b.lavine <at> gmail.com>
Cc: 13074 <at> debbugs.gnu.org
Subject: Re: bug#13074: VM Segfaults with Bad `Call' Instruction
Date: Wed, 05 Dec 2012 23:14:08 +0100
Noah Lavine <noah.b.lavine <at> gmail.com> skribis:

> That makes sense. I hit this error in debugging a CPS->GLIL compiler (which
> I hope will become Guile's compiler, but that's another story). However,
> once the debugging is done, I suppose it won't make a difference.

Oooh, make sure to post about your plans.

> What do you think about enabling it only in the debug VM, or something like
> that? Then if there's some way for me to run my code in debug mode, I can
> get the better output without slowing down most things.

I’m inclined to leave it as is, because it’s only hit when generating
wrong code.  How strongly do you feel about it?  :-)

Ludo’.




Information forwarded to bug-guile <at> gnu.org:
bug#13074; Package guile. (Tue, 11 Dec 2012 04:18:01 GMT) Full text and rfc822 format available.

Message #20 received at 13074 <at> debbugs.gnu.org (full text, mbox):

From: Noah Lavine <noah.b.lavine <at> gmail.com>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 13074 <at> debbugs.gnu.org
Subject: Re: bug#13074: VM Segfaults with Bad `Call' Instruction
Date: Mon, 10 Dec 2012 23:16:26 -0500
[Message part 1 (text/plain, inline)]
On Wed, Dec 5, 2012 at 5:14 PM, Ludovic Courtès <ludo <at> gnu.org> wrote:

> Noah Lavine <noah.b.lavine <at> gmail.com> skribis:
>
> > That makes sense. I hit this error in debugging a CPS->GLIL compiler
> (which
> > I hope will become Guile's compiler, but that's another story). However,
> > once the debugging is done, I suppose it won't make a difference.
>
> Oooh, make sure to post about your plans.


I will post more when I have more code to show, but basically it's the same
idea as the CPS-to-RTL experiment earlier. The difference is that in that
post I said that adding two new things at the same time (CPS and RTL) was
probably a bad idea. Now I'm doing something about it, by making the CPS
compiler generate GLIL instead. I hope this will be an easier path towards
a nicer compiler.


> > What do you think about enabling it only in the debug VM, or something
> like
> > that? Then if there's some way for me to run my code in debug mode, I can
> > get the better output without slowing down most things.
>
> I’m inclined to leave it as is, because it’s only hit when generating
> wrong code.  How strongly do you feel about it?  :-)
>

Well, I just fixed the bug, so I feel fine right now. :-)

In general, I do think there should at least be an option for having full
error-checking in the VM. It would have been much, much harder for me to
find this without having patched the VM, because it would have taken me a
very long time to try each new thing I tried, because I would have had to
restart Guile. I am happy for it not to be on the regular code-path,
though. I also realize that writing a compiler is an unusual application,
so maybe it should even be a compile-time option for users who prefer their
Guile slow. How does that sound?

Noah
[Message part 2 (text/html, inline)]

Reply sent to ludo <at> gnu.org (Ludovic Courtès):
You have taken responsibility. (Tue, 11 Dec 2012 09:43:01 GMT) Full text and rfc822 format available.

Notification sent to Noah Lavine <noah.b.lavine <at> gmail.com>:
bug acknowledged by developer. (Tue, 11 Dec 2012 09:43:02 GMT) Full text and rfc822 format available.

Message #25 received at 13074-done <at> debbugs.gnu.org (full text, mbox):

From: ludo <at> gnu.org (Ludovic Courtès)
To: Noah Lavine <noah.b.lavine <at> gmail.com>
Cc: 13074-done <at> debbugs.gnu.org
Subject: Re: bug#13074: VM Segfaults with Bad `Call' Instruction
Date: Tue, 11 Dec 2012 10:42:09 +0100
Hi!

Noah Lavine <noah.b.lavine <at> gmail.com> skribis:

> In general, I do think there should at least be an option for having full
> error-checking in the VM. It would have been much, much harder for me to
> find this without having patched the VM, because it would have taken me a
> very long time to try each new thing I tried, because I would have had to
> restart Guile. I am happy for it not to be on the regular code-path,
> though. I also realize that writing a compiler is an unusual application,
> so maybe it should even be a compile-time option for users who prefer their
> Guile slow. How does that sound?

The VM does full error checking.  But there’s a difference between
checking whether an object has the expected type, and checking whether
an object is a well-formed ‘SCM’ object (and NULL is not a valid ‘SCM’
object.)

Guile never does the latter, and as a rule of thumb I would keep things
this way.

The brave hacker working on a compiler can easily figure out what how to
debug all sorts of crazy things.  :-)

So I’m closing it for now.

Thanks,
Ludo’.

PS: It’s still unclear to me how you ended up forging an invalid SCM
    object.  I think you either have to generate invalid bytecode, or to
    use (pointer->scm %null-pointer), or variants thereof.




Information forwarded to bug-guile <at> gnu.org:
bug#13074; Package guile. (Tue, 11 Dec 2012 13:34:02 GMT) Full text and rfc822 format available.

Message #28 received at 13074-done <at> debbugs.gnu.org (full text, mbox):

From: Noah Lavine <noah.b.lavine <at> gmail.com>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 13074-done <at> debbugs.gnu.org
Subject: Re: bug#13074: VM Segfaults with Bad `Call' Instruction
Date: Tue, 11 Dec 2012 08:32:26 -0500
[Message part 1 (text/plain, inline)]
On Tue, Dec 11, 2012 at 4:42 AM, Ludovic Courtès <ludo <at> gnu.org> wrote:
>
> The VM does full error checking.  But there’s a difference between
> checking whether an object has the expected type, and checking whether
> an object is a well-formed ‘SCM’ object (and NULL is not a valid ‘SCM’
> object.)
>
> Guile never does the latter, and as a rule of thumb I would keep things
> this way.
>

Okay.


> The brave hacker working on a compiler can easily figure out what how to
> debug all sorts of crazy things.  :-)
>

Yes, "easily". :-)


> So I’m closing it for now.
>
> Thanks,
> Ludo’.
>
> PS: It’s still unclear to me how you ended up forging an invalid SCM
>     object.  I think you either have to generate invalid bytecode, or to
>     use (pointer->scm %null-pointer), or variants thereof.
>

I loaded a procedure on the stack, used the new-frame instruction, and then
the call instruction. When I switched the order of the first two things,
the problem went away. I must have been using uninitialized stack space.

Noah
[Message part 2 (text/html, inline)]

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 09 Jan 2013 12:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 12 years and 216 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.