xslate / p5-Text-Xslate

Scalable template engine for Perl5
https://metacpan.org/release/Text-Xslate
Other
121 stars 47 forks source link

segmentation fault (core dumped) #211

Closed hernan604 closed 1 year ago

hernan604 commented 1 year ago

Hi guys!

Im trying to debug why i am getting a segmentation fault in the XS version (in ::PP it works fine).

The first paste causes a segmentation fault. However the second paste works fine. The difference is the place where the {{ ..json_parse() }} is called.

When it is called before the :cascade it causes segmentation fault. However when its called inside the override content-> it works fine

Broken version, causes segmentation fault:

use strict;
use warnings;
use Text::Xslate;
use Path::Tiny;
use feature qw|say|;

$Text::Xslate::Util::DEBUG = "dump=load";

my $xslate = Text::Xslate->new(
  tag_start => '{{',
  tag_end   => '}}',
  function => {
    json_parse => sub { return { test => 123 } } 
  }
); 

path( "header.tpl" )->spew( "Here is the HEADER\n" );

path( "wrapper.tpl" )->spew( <<'WRAPPER');
= Wrapper BEGIN

: include 'header.tpl'
{{ block content -> { }}default content{{ } }}

= Wrapper END
WRAPPER

path( "body.tpl" )->spew( <<'BODY');
  {{
    my $x = json_parse();
  -}}
: cascade 'wrapper.tpl';
: override content -> {
here is the body {{ $x.test }}
: }
BODY

say $xslate->render( 'body.tpl' );
OUTPUT:

perl -I/home/administrator/perl/local/lib/perl5 xslate_bug.pl
[1]    24710 segmentation fault (core dumped)  perl -I/home/administrator/perl/local/lib/perl5 xslate_bug.pl

Wokring version, does not cause segmentation fault:

use strict;
use warnings;
use Text::Xslate;
use Path::Tiny;
use feature qw|say|;

$Text::Xslate::Util::DEBUG = "dump=load";

my $xslate = Text::Xslate->new(
  tag_start => '{{',
  tag_end   => '}}',
  function => {
    json_parse => sub { return { test => 123 } } 
  }
); 

path( "header.tpl" )->spew( "Here is the HEADER\n" );

path( "wrapper.tpl" )->spew( <<'WRAPPER');
= Wrapper BEGIN

: include 'header.tpl'
{{ block content -> { }}default content{{ } }}

= Wrapper END
WRAPPER

path( "body.tpl" )->spew( <<'BODY');
: cascade 'wrapper.tpl';
: override content -> {
  {{
    my $x = json_parse();
  -}}
here is the body {{ $x.test }}
: }
BODY

say $xslate->render( 'body.tpl' );
Output:

= Wrapper BEGIN

Here is the HEADER
  here is the body 123

= Wrapper END

Broken version with ::PP works:

use strict;
use warnings;
use Text::Xslate::PP;
use Path::Tiny;
use feature qw|say|;

$Text::Xslate::Util::DEBUG = "dump=load";

my $xslate = Text::Xslate->new(
  tag_start => '{{',
  tag_end   => '}}',
  function => {
    json_parse => sub { return { test => 123 } }
  }
); 

path( "header.tpl" )->spew( "Here is the HEADER\n" );

path( "wrapper.tpl" )->spew( <<'WRAPPER');
= Wrapper BEGIN

: include 'header.tpl'
{{ block content -> { }}default content{{ } }}

= Wrapper END
WRAPPER

path( "body.tpl" )->spew( <<'BODY');
  {{
    my $x = json_parse();
  -}}
: cascade 'wrapper.tpl';
: override content -> {
here is the body {{ $x.test }}
: }
BODY

say $xslate->render( 'body.tpl' );
OUTPUT: 

= Wrapper BEGIN

Here is the HEADER
here is the body 

= Wrapper END
syohex commented 1 year ago

https://metacpan.org/pod/Text::Xslate#function-=%3E-\%functions

The document says Note that these registered functions have to return a text string. json_parse must return string type, not hash reference type.

syohex commented 1 year ago

memo: backtrace

%  lldb -- ~/.plenv/versions/5.38.0/bin/perl xslate.pl 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/llvm-15/lib/python3.11/site-packages/lldb/__init__.py", line 96, in <module>
    import six
ModuleNotFoundError: No module named 'six'
(lldb) target create "/home/syohei/.plenv/versions/5.38.0/bin/perl"
Current executable set to '/home/syohei/.plenv/versions/5.38.0/bin/perl' (x86_64).
(lldb) settings set -- target.run-args  "xslate.pl"
(lldb) run
Process 20108 launched: '/home/syohei/.plenv/versions/5.38.0/bin/perl' (x86_64)
Process 20108 stopped
* thread #1, name = 'perl', stop reason = signal SIGSEGV: invalid address (fault address: 0xc)
    frame #0: 0x00007ffff7e5af71 Xslate.so`tx_fetch(my_perl=0x00005555559102a0, st=0x00007fffffffe3c0, var=0x0000000000000000, key=0x000055555615e690) at Xslate.xs:413:5
   410  tx_fetch(pTHX_ tx_state_t* const st, SV* const var, SV* const key) {
   411      SV* retval;
   412
-> 413      SvGETMAGIC(var);
   414      if(SvROK(var) && SvOBJECT(SvRV(var))) {
   415          dSP;
   416          PUSHMARK(SP);
(lldb) print var
(SV *const) $0 = NULL
(lldb) bt
* thread #1, name = 'perl', stop reason = signal SIGSEGV: invalid address (fault address: 0xc)
  * frame #0: 0x00007ffff7e5af71 Xslate.so`tx_fetch(my_perl=0x00005555559102a0, st=0x00007fffffffe3c0, var=0x0000000000000000, key=0x000055555615e690) at Xslate.xs:413:5
    frame #1: 0x00007ffff7e5b732 Xslate.so`tx_runops [inlined] TXCODE_fetch_field_s(txst=0x00007fffffffe3c0, my_perl=0x00005555559102a0) at xslate_opcode.inc:143:16
    frame #2: 0x00007ffff7e5b71c Xslate.so`tx_runops(my_perl=0x00005555559102a0, st=0x00007fffffffe3c0) at xslate_ops.h:517:34
    frame #3: 0x00007ffff7e5e1be Xslate.so`tx_execute(my_perl=0x00005555559102a0, my_cxtp=0x0000555555b3f8e0, base=0x000055555614db50, output=<unavailable>, hv=<unavailable>) at Xslate.xs:963:9
    frame #4: 0x00007ffff7e5e4c4 Xslate.so`XS_Text__Xslate__Engine_render(my_perl=0x00005555559102a0, cv=<unavailable>) at Xslate.xs:1645:9
    frame #5: 0x0000555555697fe0 perl`Perl_pp_entersub + 544
    frame #6: 0x000055555568dd86 perl`Perl_runops_standard + 22
    frame #7: 0x00005555555c3a75 perl`perl_run + 965
    frame #8: 0x0000555555599562 perl`main + 338
    frame #9: 0x00007ffff7c23a90 libc.so.6`__libc_start_call_main(main=(perl`main), argc=2, argv=0x00007fffffffe8a8) at libc_start_call_main.h:58:16
    frame #10: 0x00007ffff7c23b49 libc.so.6`__libc_start_main_impl(main=(perl`main), argc=2, argv=0x00007fffffffe8a8, init=<unavailable>, fini=<unavailable>, rtld_fini=<unavailable>, stack_end=0x00007fffffffe898) at libc-start.c:360:3
    frame #11: 0x00005555555995a5 perl`_start + 37
(lldb)
hernan604 commented 1 year ago

Ah

https://metacpan.org/pod/Text::Xslate#function-=%3E-\%functions

The document says Note that these registered functions have to return a text string. json_parse must return string type, not hash reference type.

It seems to also fail when i changed json_parse to return a string.

Thanks for checking it out!