bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Segfault on function crashing argument


From: Aharon Robbins
Subject: Re: Segfault on function crashing argument
Date: Wed, 17 Feb 2010 23:23:37 +0200

Greetings. Re this:

> Date: Tue, 16 Feb 2010 19:55:04 +0100
> From: Seb <address@hidden>
> To: address@hidden
> Subject: Segfault on function crashing argument
> 
> Hello,
> 
> I've encountered a weird behaviour with gawk (3.1.7) which looks like a bug 
> very
> much. I search the ML archives but I found nothing relative, so I post a 
> report;
> apologies if this has already been discussed/fixed. :)
> 
> It appears when a function exiting the program is passed to another one. There
> is no problem if the mother function has exactly the amount of arguments its
> "prototype" has declared and if the child exiting function is the last one of
> them. All the other cases draw to an internal error.
> 
> I join a little script which shows the bug with three tests. Here are the
> results I get (the number as argument requests the matching test):
> 
> $ awk -f debug.awk 1
>  true(1, 1, crash()) => crash properly.
> 
> $ awk -f debug.awk 2
>  true(1, crash(), 1) => do not crash properly.
>  awk: /tmp/debug.awk:5: fatal error: internal error: segfault
>  Abandon
> 
> $ awk -f debug.awk 3
>  true(1, crash()) => do not crash properly.
>  awk: /tmp/debug.awk:5: fatal error: internal error: segfault
>  Abandon
> 
> otawk (one true awk) and mawk complain about none of these tests, it's really 
> a
> gawk-specific behaviour.
> 
> ++
> Seb.
> 
> --Multipart=_Tue__16_Feb_2010_19_55_04_+0100_mYtIyZPXH4ojn1iE
> Content-Type: application/octet-stream;
>  name="debug.awk"
> Content-Disposition: attachment;
>  filename="debug.awk"
> Content-Transfer-Encoding: base64
> 
> #!/bin/awk -f
> 
> function crash () {
>     exit 1
> }
> 
> function true (a,b,c) {
>     return 0
> }
> 
> BEGIN {
>     if (ARGV[1] == 1) {
>         print "true(1, 1, crash()) => crash properly."
>         true(1, 1, crash())
>     } else if (ARGV[1] == 2) {
>         print "true(1, crash(), 1) => do not crash properly."
>         true(1, crash(),1)
>     } else {
>         print "true(1, crash()) => do not crash properly."
>         true(1, crash())
>     }
> }
> 
> # FdF
> 
> --Multipart=_Tue__16_Feb_2010_19_55_04_+0100_mYtIyZPXH4ojn1iE--

This is a bug. Thank you for reporting it.  The patch below fixes it.

Arnold
-------------------------------------------------------------
Wed Feb 17 23:19:32 2010  Arnold D. Robbins  <address@hidden>

        * eval.c (pop_fcall): Check that argument on stack is not NULL before
        attempting to clear it; add comment explaining it.
        (push_args): Set nodes to zero for argument to make sure that values
        are NULL for testing later in pop_fcall. See test/fcall_exit.awk. Thanks
        to Seb <address@hidden>.

Index: eval.c
===================================================================
RCS file: /d/mongo/cvsrep/gawk-stable/eval.c,v
retrieving revision 1.17
diff -u -r1.17 eval.c
--- eval.c      9 Jul 2009 19:21:15 -0000       1.17
+++ eval.c      17 Feb 2010 21:18:23 -0000
@@ -1760,6 +1760,14 @@
 
        for (count = fcalls[curfcall].count; count > 0; count--) {
                n = *sp++;
+               /*
+                * If, while setting the value of an argument in push_args,
+                * the recursively evaluating code exits, this argument
+                * could never have been set to a value. So check for NULL,
+                * first.
+                */
+               if (n == NULL)
+                       continue;
                if (n->type == Node_var)                /* local variable */
                        unref(n->var_value);
                else if (n->type == Node_var_array)     /* local array */
@@ -1820,6 +1828,7 @@
        /* for each calling arg. add NODE * on stack */
        for (i = 0; i < count; i++) {
                getnode(r);
+               memset(r, 0, sizeof(*r));
                *sp++ = r;
                if (argp == NULL) {
                        /* local variable */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]