ragel icon indicating copy to clipboard operation
ragel copied to clipboard

ragel 6.10 segfault

Open basiliscos opened this issue 3 years ago • 0 comments

Hi,

When I generate C++ sources via command line :

ragel ServerBinaryControlParser.rl -o ServerBinaryControlParser.cc

it segfaults. When I see the generated graph (ragel ServerBinaryControlParser.rl -p -V > /tmp/my.gv) it seems ok. When I change the line m_destination (commented), then it generates C++ sources right again (but I think my original grammar is correct).

The sources, slightly minimized can be found below.

Binary.rl

%%{
    machine binary;
    action mark              {}
    action record_client_id  {}
    action push_len          {}
    action reset_len         {}
    action has_more          {}

    ###########################
    # message related actions #
    ###########################

    action push_arr_len  { }
    action reset_arr_len { }
    action has_more_arr  {}


    action param_name {}
    action param_type {}
    action param_text { param_value = Consume();}

    action move_bool { }
    action move_s8   { }
    action move_u8   { }
    action move_s16  { }
    action move_u16  { }
    action move_s32  { }
    action move_u32  { }
    action move_s64  { }
    action move_u64  { }
    action move_f32  { }
    action move_f64  { }

    action move_text   { }
    action move_binary { }

    action reset_param { }
    action add_u8      { }
    action add_s8      { }
    action add_u16     { }
    action add_s16     { }
    action add_u32     { }
    action add_s32     { }
    action add_u64     { }
    action add_s64     { }
    action add_f32     { }
    action add_f64     { }

    action push_bool { }
    action push_s8   { }
    action push_u8   { }
    action push_s16  { }
    action push_u16  { }
    action push_s32  { }
    action push_u32  { }
    action push_s64  { }
    action push_u64  { }
    action push_f32  { }
    action push_f64  { }

    action reset_a_bool {  }
    action reset_a_s8   { }
    action reset_a_u8   { }
    action reset_a_s16  { }
    action reset_a_u16  { }
    action reset_a_s32  { }
    action reset_a_u32  { }
    action reset_a_s64  { }
    action reset_a_u64  { }
    action reset_a_f32  { }
    action reset_a_f64  { }

    action move_a_bool {}
    action move_a_s8   { }
    action move_a_u8   { }
    action move_a_s16  { }
    action move_a_u16  { }
    action move_a_s32  { }
    action move_a_u32  { }
    action move_a_s64  { }
    action move_a_u64  { }
    action move_a_f32  { }
    action move_a_f64  { }

    t_connect      = /connect/i;
    t_protocol     = /protocol/i;
    t_binary       = /binary/i;
    t_console      = /console/i;

    t_ok           = 0x00 0x4F 0x4B 0x00;
    t_error        = 0x01 0x45 0x52 0x52;
    t_accepted     = 0x00 0x41 0x43 0x43;
    t_rejected     = 0x00 0x52 0x45 0x4A;
    t_pending      = 0x00 0x50 0x45 0x4E;
    t_end          = 0x00 0x45 0x4E 0x44;
    t_sync         = 0x53 0x59 0x4E 0x43;
    t_heartbeat    = 0x00 0x48 0x45 0x41;
    t_notification = 0x01 0x4E 0x54 0x46;
    t_message      = 0x00 0x4D 0x45 0x53;
    t_data         = 0x01 0x44 0x41 0x54;
    t_command      = 0x01 0x43 0x4F 0x4D;
    t_query        = 0x01 0x51 0x55 0x45;

    string_len     = any{2} >reset_len $push_len;
    string         = (any when has_more )** >mark;


    arr_len     = any{2} >reset_arr_len $push_arr_len;

    param_bool         = (0x00 | 0x01) >reset_param $add_u8;
    param_num_s8       = any{1} >reset_param $add_s8 ;
    param_num_u8       = any{1} >reset_param $add_u8 ;
    param_num_s16      = any{2} >reset_param $add_s16;
    param_num_u16      = any{2} >reset_param $add_u16;
    param_num_s32      = any{4} >reset_param $add_s32;
    param_num_u32      = any{4} >reset_param $add_u32;
    param_num_s64      = any{8} >reset_param $add_s64;
    param_num_u64      = any{8} >reset_param $add_u64;
    param_num_f32      = any{4} >reset_param $add_f32;
    param_num_f64      = any{8} >reset_param $add_f64;

    param_value_b   = 0x01 0x00 'B'   <: param_bool    %move_bool;
    param_value_s8  = 0x02 0x00 'S8'  <: param_num_s8  %move_s8 ;
    param_value_u8  = 0x02 0x00 'U8'  <: param_num_u8  %move_u8 ;
    param_value_s16 = 0x03 0x00 'S16' <: param_num_s16 %move_s16;
    param_value_u16 = 0x03 0x00 'U16' <: param_num_u16 %move_u16;
    param_value_s32 = 0x03 0x00 'S32' <: param_num_s32 %move_s32;
    param_value_u32 = 0x03 0x00 'U32' <: param_num_u32 %move_u32;
    param_value_s64 = 0x03 0x00 'S64' <: param_num_s64 %move_s64;
    param_value_u64 = 0x03 0x00 'U64' <: param_num_u64 %move_u64;
    param_value_f32 = 0x03 0x00 'F32' <: param_num_f32 %move_f32;
    param_value_f64 = 0x03 0x00 'F64' <: param_num_f64 %move_f64;

    param_arr_b   = 0x02 0x00 'B*'   <: arr_len (param_bool    @{++arr_raw_counter;} %push_bool when has_more_arr)** >reset_a_bool %move_a_bool;
    param_arr_s8  = 0x03 0x00 'S8*'  <: arr_len (param_num_s8  @{++arr_raw_counter;} %push_s8   when has_more_arr)** >reset_a_s8   %move_a_s8  ;
    param_arr_u8  = 0x03 0x00 'U8*'  <: arr_len (param_num_u8  @{++arr_raw_counter;} %push_u8   when has_more_arr)** >reset_a_u8   %move_a_u8  ;
    param_arr_s16 = 0x04 0x00 'S16*' <: arr_len (param_num_s16 @{++arr_raw_counter;} %push_s16  when has_more_arr)*  >reset_a_s16  %move_a_s16 ;
    param_arr_u16 = 0x04 0x00 'U16*' <: arr_len (param_num_u16 @{++arr_raw_counter;} %push_u16  when has_more_arr)** >reset_a_u16  %move_a_u16 ;
    param_arr_s32 = 0x04 0x00 'S32*' <: arr_len (param_num_s32 @{++arr_raw_counter;} %push_s32  when has_more_arr)** >reset_a_s32  %move_a_s32 ;
    param_arr_u32 = 0x04 0x00 'U32*' <: arr_len (param_num_u32 @{++arr_raw_counter;} %push_u32  when has_more_arr)** >reset_a_u32  %move_a_u32 ;
    param_arr_s64 = 0x04 0x00 'S64*' <: arr_len (param_num_s64 @{++arr_raw_counter;} %push_s64  when has_more_arr)** >reset_a_s64  %move_a_s64 ;
    param_arr_u64 = 0x04 0x00 'U64*' <: arr_len (param_num_u64 @{++arr_raw_counter;} %push_u64  when has_more_arr)** >reset_a_u64  %move_a_u64 ;
    param_arr_f32 = 0x04 0x00 'F32*' <: arr_len (param_num_f32 @{++arr_raw_counter;} %push_f32  when has_more_arr)** >reset_a_f32  %move_a_f32 ;
    param_arr_f64 = 0x04 0x00 'F64*' <: arr_len (param_num_f64 @{++arr_raw_counter;} %push_f64  when has_more_arr)** >reset_a_f64  %move_a_f64 ;

    param_scalar_value  = param_value_b
                        | param_value_s8  | param_value_u8
                        | param_value_s16 | param_value_u16
                        | param_value_s32 | param_value_u32
                        | param_value_s64 | param_value_u64
                        | param_value_f32 | param_value_f64
                        ;

    param_array_value   = param_arr_b
                        | param_arr_s8  | param_arr_u8
                        | param_arr_s16 | param_arr_u16
                        | param_arr_s32 | param_arr_u32
                        | param_arr_s64 | param_arr_u64
                        | param_arr_f32 | param_arr_f64
                        ;

    param_text_type     = '=' string_len <: string %param_type;
    param_text          = param_text_type <: string_len <: string %param_text %move_text;
    param_binary_type   = '$' string_len <: string %param_type;
    param_binary        = param_binary_type <: string_len <: string %param_text %move_binary;

    param_value         = param_scalar_value | param_array_value;
    param_name          = string_len <: string %param_name;
    param_fixed         = '@' <: param_name <: param_value;
    param_dynamic       = '#' <: param_name <: (param_text | param_binary);

    param               = param_fixed | param_dynamic;
    mesage_body         = param**;

}%%

ServerBinaryControlParser.rl

%%{
    machine binary_server_parser;
    include binary "Binary.rl";

    action done               {  }
    action push_heartbeat     {  }
    action push_cmd_register  {  }
    action push_cmd_subscribe {  }
    action push_message       {  }

    action role_add    {  }
    action role_remove {  }
    action subs_add    { }
    action subs_remove { }

    action record_role        { }
    action record_dest_role   { }
    action record_dest_client { }
    action record_dest_bc     { }

    action record_delivery_all {  }
    action record_delivery_no  { }
    action record_delivery_any { }

    action record_message_name { }

    action push_q_role_list          { }
    action push_q_client_list        { }
    action push_q_client_list_roles  { }
    action push_q_clients_with_roles { }

    cmd_role_add    = 0x03 0x00 'add'    <: string_len string %role_add;
    cmd_role_remove = 0x06 0x00 'remove' <: string_len string %role_remove;
    cmd_header_role = '>' <: (cmd_role_add | cmd_role_remove);
    cmd_register    = t_command 0x0D 0x00 'ROLE-REGISTER' <: cmd_header_role** %push_cmd_register;

    cmd_subs_add    = 0x03 0x00 'add'    <: string_len string %subs_add;
    cmd_subs_remove = 0x06 0x00 'remove' <: string_len string %subs_remove;
    cmd_header_subs = '>' <: (cmd_subs_add | cmd_subs_remove);
    cmd_subscribe   = t_command <: 0x0E <: 0x00 <:  'ROLE-SUBSCRIBE' <: cmd_header_subs** %push_cmd_subscribe;

    delivery_all   = 0x00 %record_delivery_all;
    delivery_no    = 0xFF  %record_delivery_no;
    delivery_any   = 0x01 %record_delivery_any;
    single_dest    = string_len <: (('@' <: string >mark %record_dest_role ) | string %record_dest_client);
    m_delivery     = (delivery_all | delivery_no | delivery_any);
    m_broadcast    = 0xFF 0xFF  %record_dest_bc;
    #m_destination  = m_broadcast | ((arr_len --  m_broadcast) <: single_dest single_dest**);
    m_destination  = m_broadcast | ((arr_len)  single_dest single_dest**);
    m_name         = t_data string_len <: string %record_message_name;

    client_id            = string_len string  %record_client_id;
    client_role          = string_len string %record_role;
    q_h_client_id        = '>' 0x02 0x00 'id' <:  client_id;
    q_h_role             = '>' 0x04 0x00 'role'   client_role;
    q_role_list          = 0x09 0x00 <: 'ROLE-LIST' %push_q_role_list;
    q_client_list        = 0x0A 0x00 <: 'CLIENT-LIST' %push_q_client_list;
    q_client_list_roles  = 0x11 0x00 <: 'CLIENT-LIST-ROLES' <: q_h_client_id %push_q_client_list_roles;
    q_clients_with_roles = 0x11 0x00 <: 'CLIENTS-WITH-ROLE' <: q_h_role      %push_q_clients_with_roles;

    query_body = q_role_list | q_client_list | q_client_list_roles | q_clients_with_roles;
    cmd_body   = cmd_register | cmd_subscribe;
    command    = cmd_body <: t_end;
    query      = t_query <: query_body <: t_end;
    heartbeat  = t_heartbeat  %push_heartbeat;
    message    = t_message m_delivery <: m_destination <: t_end <: m_name <: mesage_body %push_message <: t_end;
    start    := t_sync (heartbeat | command | query | message) @done;
}%%

#include <cmath>
#include "ServerBinaryControlParser.hpp"

namespace stheno::proto::parser {
using namespace stheno::proto::protocol;

%% write data;

ServerBinaryControlParser::ServerBinaryControlParser() noexcept {
    Reset();
}

size_t ServerBinaryControlParser::Parse(const std::string_view& data) noexcept {
    pb  = data.data();
    pe  = pb + data.length();
    p   = pb;
    eof = pe;
    %% write exec;
    return p - pb;
}

bool ServerBinaryControlParser::Success() noexcept {
    return cs >= binary_server_parser_first_final;
}

void ServerBinaryControlParser::Reset() noexcept {
    state = State::NONE;
    cs = binary_server_parser_en_start;
}

}

basiliscos avatar May 24 '21 08:05 basiliscos