Skip Menu |

This queue is for tickets about the Future-AsyncAwait CPAN distribution.

Report information
The Basics
Id: 130417
Status: resolved
Priority: 0/
Queue: Future-AsyncAwait

People
Owner: Nobody in particular
Requestors: leonerd-cpan [...] leonerd.org.uk
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in:
  • 0.30
  • 0.31
  • 0.31_003
Fixed in: 0.32



Subject: `async` casues strictness failures to segfault
package segfault; use strict; use warnings; use Future::AsyncAwait; async sub example { $x } 1; $ perl ex.pl Segmentation fault -- Paul Evans
Early analysis: $ gdb --args $HOME/perl5/perlbrew/perls/bleadperl/bin/perl -Mblib rt130417.pl ... (gdb) run Starting program: /home/leo/perl5/perlbrew/perls/bleadperl/bin/perl -Mblib rt130417.pl [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7fbf45b in async_keyword_plugin (op_ptr=0x7fffffffcf58) at lib/Future/AsyncAwait.xs:2246 2246 if(CvLVALUE(cv)) (gdb) p cv $1 = (CV *) 0x0 -- Paul Evans
This appears to come from the fact that even after a strictness error, parse_block() does not croak but instead returns a valid(?) OP pointer and sets the parser error count: body=0x555555bc3be0, parser->error_count=1 As yet I'm not sure what to do about this situation, how I propagate that back up myself. I'll have a look and see if I can find any inspiration in similar keyword plugins by MAUKE or ZEFRAM. -- Paul Evans
It seems I just have to set something valid in the op_ptr and return the appropriate keyword result. I'll set NULL. Tested fine on all my perlbrews - 5.16 to 5.30. -- Paul Evans
Subject: rt130417.patch
=== modified file 'lib/Future/AsyncAwait.xs' --- lib/Future/AsyncAwait.xs 2019-08-14 15:42:29 +0000 +++ lib/Future/AsyncAwait.xs 2019-08-30 11:26:29 +0000 @@ -2219,6 +2219,22 @@ SvREFCNT_inc(PL_compcv); body = block_end(save_ix, body); + if(PL_parser->error_count) { + /* parse_block() still returns a valid body even if a parse error happens. + * We need to destroy this partial body before returning a valid(ish) + * state to the keyword hook mechanism, so it will find the error count + * correctly + * See https://rt.cpan.org/Ticket/Display.html?id=130417 + */ + op_free(body); +#ifdef HAVE_PARSE_SUBSIGNATURE + if(sigop) + op_free(sigop); +#endif + *op_ptr = NULL; + return name ? KEYWORD_PLUGIN_STMT : KEYWORD_PLUGIN_EXPR; + } + #ifdef HAVE_PARSE_SUBSIGNATURE if(sigop) body = op_append_list(OP_LINESEQ, sigop, body); === added file 't/90rt130417.t' --- t/90rt130417.t 1970-01-01 00:00:00 +0000 +++ t/90rt130417.t 2019-08-30 11:25:36 +0000 @@ -0,0 +1,24 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More; + +ok( !defined eval q' + package segfault; + use strict; + use warnings; + + use Future::AsyncAwait; + + async sub example { + $x + } + ', + 'strict-failing code fails to compile' ); + +like( "$@", qr/^Global symbol "\$x" requires explicit package name/, + 'Failure message complains about undeclared $x' ); + +done_testing;
Released in 0.32 -- Paul Evans