Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ragel 6.10 segfault #69

Open
basiliscos opened this issue May 24, 2021 · 0 comments
Open

ragel 6.10 segfault #69

basiliscos opened this issue May 24, 2021 · 0 comments

Comments

@basiliscos
Copy link

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;
}

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant