objectcomputing / mFAST

A FAST (FIX Adapted for STreaming) encoder/decoder
http://objectcomputing.github.io/mFAST
BSD 3-Clause "New" or "Revised" License
220 stars 114 forks source link

segfault on encoding string values #115

Open quant61 opened 2 years ago

quant61 commented 2 years ago

When I try to encode entry with string fields binary gets segmentation fault.

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(mfast0)

FIND_PACKAGE(mFAST REQUIRED COMPONENTS
             coder ## needed only for FAST encoder/decoder
)
INCLUDE_DIRECTORIES(${MFAST_INCLUDE_DIR})
LINK_DIRECTORIES(${MFAST_LIBRARY_DIRS})

FASTTYPEGEN_TARGET(model test.xml)

set (CMAKE_CXX_STANDARD 20)

add_executable (mfast0 ${FASTTYPEGEN_model_OUTPUTS} mfast0.cpp)
target_link_libraries (mfast0 ${MFAST_LIBRARIES} )

docker-compose.yml

version: '3.4'
services:
  compiler:
    image: compiler
    build:
      context: .
    command: sh

Dockerfile

FROM madduci/docker-linux-cpp

RUN apt update
RUN apt upgrade -y
RUN apt install -y cmake curl git

RUN cd / && curl -L https://boostorg.jfrog.io/artifactory/main/release/1.72.0/source/boost_1_72_0.tar.gz | tar zx

# BOOOST.BOOTSTRAP!!!
# Y U CANNO SPECIFY VERSION FOR CLANG++ ???!!!
RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-12 90 --slave /usr/bin/clang++ clang++ /usr/bin/clang++-12

RUN cd /boost_1_72_0 && ./bootstrap.sh -with-toolset=clang  \
    && ./b2 && ./b2 install

RUN git clone --recursive https://github.com/objectcomputing/mFAST.git /mFAST && sleep 0
RUN mkdir /mFAST/build

RUN cd /mFAST/build \
    && cmake -DBOOST_ROOT=/boost_1_72_0 \
    -DBoost_INCLUDE_DIR=/boost_1_72_0 \
    -DCMAKE_C_COMPILER=/usr/bin/clang-12 \
    -DCMAKE_CXX_COMPILER=/usr/bin/clang++-12 \
    -DBUILD_SHARED_LIBS=ON \
    .. \
    && make

RUN cd /mFAST/build && make install

RUN apt install -y gdb

ADD mfast0.cpp test.xml CMakeLists.txt /app/
WORKDIR /app
RUN mkdir build && cd build && cmake ..
RUN cd build && make && mv mfast0 ..

ENTRYPOINT []

test.xml

<?xml version="1.0" encoding="UTF-8"?>
<templates xmlns="http://www.fixprotocol.org/ns/fast/td/1.1">
    <template xmlns="http://www.fixprotocol.org/ns/fast/td/1.1" name="X-Test0" id="1">
        <string name="Name" id="13"/>
        <uInt64 name="Number" id="42"/>
    </template>
</templates>

mfast0.cpp


#include <stdint.h>
#include <stdbool.h>
#include <string>

#include <mfast.h>
#include <mfast/allocator.h>
#include <mfast/malloc_allocator.h>
#include <mfast/coder/fast_encoder.h>
#include "build/test.h"

using mfast::ascii_string_cref;

using namespace std;

mfast::fast_encoder init_encoder(){

    mfast::malloc_allocator malloc_allc;
    mfast::allocator* alloc = &malloc_allc;

    const mfast::templates_description* descriptions[] = { test::description() };

    mfast::fast_encoder encoder(&malloc_allc);

    encoder.include(descriptions);
    return encoder;
}

int main(){
    mfast::fast_encoder encoder = init_encoder();

    test::X_Test0 msg;
    test::X_Test0_mref mref = msg.mref();

    string name = "foo";

//     mref.set_Name().append(name.data(), name.size());
    mref.set_Name().as("bar");
    mref.set_Number().as(0x123);

    char outbuf[1024];
    size_t n = encoder.encode(msg.cref(), outbuf, sizeof(outbuf), false);
    cout << n << endl;
    for(int i=0;i<n;i++){
        cout << i << ": " << (int)(uint8_t)(outbuf[i]) << endl;
    }

    return 0;
}

in host:

docker-compose build compiler
docker-compose run --rm compiler bash

When I try ./mfast0 in container I get

Segmentation fault (core dumped)

With gdb ./mfast0 I can see SIGSEGV after run

bt is

#0  0x00007ffd14b990b0 in ?? ()
#1  0x0000000000408f08 in mfast::vector_mref_base<char>::reserve (this=0x7ffd14b987c0, n=3) at /mFAST/src/mfast/coder/encoder/../../vector_ref.h:441
#2  0x0000000000408dca in mfast::vector_mref_base<char>::assign<char const*> (this=0x7ffd14b987c0, first=0x13440a0 "bar", last=0x13440a3 "") at /mFAST/src/mfast/coder/encoder/../../vector_ref.h:326
#3  0x0000000000408d45 in mfast::vector_mref_base<char>::assign<char const*> (this=0x7ffd14b987c0, first=0x13440a0 "bar", last=0x13440a3 "") at /mFAST/src/mfast/coder/encoder/../../vector_ref.h:262
#4  0x00000000004250aa in mfast::string_mref_base<char>::as (this=0x7ffd14b987c0, s=...) at /mFAST/src/mfast/coder/encoder/../../string_ref.h:159
#5  0x0000000000424d06 in mfast::fast_ostream::save_previous_value<mfast::string_cref<char> > (this=0x1343000, cref=...) at /mFAST/src/mfast/coder/encoder/fast_ostream.h:237
#6  0x0000000000424c16 in mfast::encoder_detail::no_operator::encode_impl<mfast::string_cref<char> > (this=0x4566b0 <mfast::encoder_detail::no_operator_instance>, cref=..., stream=...) at /mFAST/src/mfast/coder/encoder/encoder_field_operator.cpp:95
#7  0x0000000000423dbd in mfast::encoder_detail::no_operator::encode (this=0x4566b0 <mfast::encoder_detail::no_operator_instance>, cref=..., stream=..., pmap=...) at /mFAST/src/mfast/coder/encoder/encoder_field_operator.cpp:120
#8  0x000000000040ea61 in mfast::fast_encoder_impl::visit<mfast::string_cref<char> > (this=0x1342f70, cref=...) at /mFAST/src/mfast/coder/encoder/fast_encoder.cpp:83
#9  0x000000000040e929 in mfast::detail::result_holder<void>::apply_visitor<mfast::fast_encoder_impl, mfast::string_cref<char> > (this=0x7ffd14b98998, v=..., ref=...) at /mFAST/src/mfast/coder/encoder/../../field_visitor.h:36
#10 0x000000000040dc5e in mfast::detail::field_accessor_adaptor<mfast::fast_encoder_impl, void>::visit (this=0x7ffd14b98998, inst=0x13430d0, storage=0x7ffd14b990b0) at /mFAST/src/mfast/coder/encoder/../../field_visitor.h:87
#11 0x000000000042ece6 in mfast::ascii_field_instruction::accept (this=0x13430d0, visitor=..., context=0x7ffd14b990b0) at /mFAST/src/mfast/field_instructions.cpp:22
#12 0x000000000040a45c in mfast::apply_accessor<mfast::fast_encoder_impl> (accessor=..., v=...) at /mFAST/src/mfast/coder/encoder/../../field_visitor.h:297
#13 0x00000000004096a0 in mfast::fast_encoder_impl::visit (this=0x1342f70, cref=..., force_reset=false) at /mFAST/src/mfast/coder/encoder/fast_encoder.cpp:199
#14 0x00000000004098b5 in mfast::fast_encoder::encode (this=0x7ffd14b990f0, message=..., buffer=0x7ffd14b98c00 "\030ba\362\006\177", buffer_size=1024, force_reset=false) at /mFAST/src/mfast/coder/encoder/fast_encoder.cpp:224
#15 0x0000000000407366 in main () at /mFAST/src/mfast/value_storage.h:108
adamyg commented 1 year ago

within init_encoder()n you're assigning a locally scoped malloc_allocator, instead it must have same life-time of the associated encoder.


mfast::fast_encoder init_encoder(mfast::malloc_allocator *allocator)
{
  const mfast::templates_description* descriptions[] = {mfasttest4::description()};
  mfast::fast_encoder encoder(allocator);
  encoder.include(descriptions);
  return encoder;
}

int main()
{
  mfast::malloc_allocator allocator;
  mfast::fast_encoder encoder = init_encoder(&allocator);