logo
down
shadow

Crash in boost::archive::text_iarchive in_archive {is} boost <1.71> on g++ <7.4.0>


Crash in boost::archive::text_iarchive in_archive {is} boost <1.71> on g++ <7.4.0>

By : Pcouper
Date : September 22 2020, 11:00 AM
I hope this helps . I am trying to send a struct over TCP socket. The code below is crashing in netcom_server() function while constructing boost::archive::text_iarchive object with error below. Please see, if you could find any other flaws as well. I am running two different instances of this code - one that runs the netcom_server() function and the other that runs netcom_client(). , Several issues.
code :
std::string bufdata;
{
    std::stringstream os;
    {
        boost::archive::text_oarchive out_archive{ os };
        out_archive << snd_elem;
    }
    bufdata = os.str();
}
recvd_bloomdb.indexins_elem(recv_elem, i);
bufdata += '\x00';
sendData(client_socket, boost::asio::buffer(bufdata));
std::size_t bytes_transferred = boost::asio::read_until(socket, data, '\x00', ec);
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/asio.hpp>
#include <boost/serialization/serialization.hpp>
#include <iostream>
#include <mutex>

namespace {
    // very sumple hack to synchronize output to std::cout
    #define PRINT(e) { std::lock_guard<std::mutex> lk(s_mx); std::cout << e << std::endl; }
    static std::mutex s_mx;
}

namespace ba = boost::asio;
using ba::ip::tcp;

using string_buffer = boost::asio::dynamic_string_buffer<char, std::char_traits<char>, std::allocator<char> >;

void sendData(tcp::socket& socket, boost::asio::const_buffer data);
void getData(tcp::socket& socket, string_buffer data);

typedef struct elem {
    bool bit            = false;
    int count           = 0;
    uint64_t hashSum[2] = {};
    uint64_t idSum      = 0;

    template <typename Archive> void serialize(Archive& ar, unsigned) {
        ar& bit;
        ar& count;
        ar& hashSum[0];
        ar& hashSum[1];
        ar& idSum;
    }

    friend std::ostream& operator<<(std::ostream& os, elem const& e) {
        std::ostringstream oss;
        oss << std::showbase << std::boolalpha;

        oss << "[" << e.bit << "," 
            << std::dec << e.count << ","
            << std::hex << "{" << e.hashSum[0] << "," << e.hashSum[1] << "},"
            << e.idSum << "]";

        return os << oss.str();
    }
} element;

namespace mocks {
    struct bloom_filter {
        std::vector<elem> mock_data{
            { false, 1, { 0x7e, 0xeb }, 42 },
        };

        bloom_filter(...) {}
        size_t size() const { return mock_data.size(); }
        void indexins_elem(elem const& e, size_t i) {
            assert(i < size());
            mock_data.at(i) = e;
            //Danger: this grows the db while it is being iterated
            //mock_data.insert(mock_data.begin() + i, e);
        }
        void show_elemvec() const {
            for (auto& el : mock_data) {
                PRINT(el);
            }
        }
        void show_elem(size_t i) const { PRINT(mock_data.at(i)); }
        elem getelem(size_t i) { return mock_data.at(i); }
    };
    void set_elemvec(element& lhs, element const& rhs) { lhs = rhs; }
}

using mocks::bloom_filter;
using mocks::set_elemvec;

typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info;

void netcom_server(unsigned short portn, bloom_filter& /*bloom_db*/) {
    ba::io_service io_service;
    bloom_filter recvd_bloomdb(4, "rcvbloom_db", 4096);
    tcp::socket server_socket(io_service);
    tcp::acceptor acceptor_server(io_service, {tcp::v4(), portn});

    while (1) {
        acceptor_server.accept(server_socket);
        PRINT("Connection Accepted : " << server_socket.remote_endpoint());

        for (auto i = 0u; i < recvd_bloomdb.size(); ++i) {
            std::string bufdata;
            getData(server_socket, ba::dynamic_buffer(bufdata));
            element recv_elem;
            try {
                while (bufdata.size() && ('\x00' == bufdata.back())) {
                    bufdata.pop_back();
                }
                std::istringstream is(bufdata);
                PRINT("RECV DEBUG: " << std::quoted(is.str()));
                {
                    boost::archive::text_iarchive in_archive{ is };
                    in_archive >> recv_elem;
                }
                recvd_bloomdb.indexins_elem(recv_elem, i);
            } catch (std::exception& e) {
                PRINT(e.what());
            }
        }

        PRINT("Received " << recvd_bloomdb.size() << " elements at server");
        recvd_bloomdb.show_elemvec();
        PRINT("Close connection " << server_socket.remote_endpoint());
        server_socket.close();
    }
}

std::string archive_text(elem const& e) {
    std::stringstream os;
    {
        boost::archive::text_oarchive out_archive{ os };
        out_archive << e;
    }
    return os.str();
}

void netcom_client(unsigned short portn, std::string serverip, bloom_filter& bloom_db) {
    ba::io_service io_service;
    tcp::socket client_socket(io_service);
    client_socket.connect({ba::ip::address::from_string(serverip), portn});
    std::this_thread::sleep_for(std::chrono::seconds(1));

    for (auto i = 0u; i < bloom_db.size(); ++i) {
        bloom_db.show_elem(i);

        auto bufdata = archive_text(bloom_db.getelem(i));
        PRINT("SEND DEBUG: " << std::quoted(bufdata));
        bufdata += '\x00';
        sendData(client_socket, boost::asio::buffer(bufdata));
    }
    PRINT("Exit netcom_client");
}

void sendData(tcp::socket& socket, boost::asio::const_buffer data) {
    boost::system::error_code ec;
    std::size_t bytes_transferred = boost::asio::write(socket, data, ec);
    if (bytes_transferred == 0 && ec == boost::asio::error::would_block) {
        PRINT(" Could not send any more");
    }
    PRINT(ec.message() << "bytes sent " << bytes_transferred);
}

void getData(tcp::socket& socket, string_buffer data) {
    boost::system::error_code ec;
    std::size_t bytes_transferred = boost::asio::read_until(socket, data, '\x00', ec);
    //std::size_t bytes_transferred = boost::asio::read(socket, data, ec);
    if (bytes_transferred == 0 && ec == boost::asio::error::would_block) {
        PRINT("No data available");
    }
    PRINT(ec.message() << "bytes received " << bytes_transferred);
}

int main() {
    std::thread s([] {
        bloom_filter db;
        netcom_server(6767, db);
    });
    std::thread c([] {
        for (int i = 0; i < 4; ++i) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            bloom_filter db;
            netcom_client(6767, "127.0.0.1", db);
        }
    });

    s.join();
    c.join();
}
Connection Accepted : 127.0.0.1:38126
[false,1,{0x7e,0xeb},0x2a]
SEND DEBUG: "22 serialization::archive 17 0 0 0 1 126 235 42
"
Successbytes sent 49
Exit netcom_client
Successbytes received 49
RECV DEBUG: "22 serialization::archive 17 0 0 0 1 126 235 42
"
Received 1 elements at server
[false,1,{0x7e,0xeb},0x2a]
Close connection 127.0.0.1:38126
Connection Accepted : 127.0.0.1:38128
[false,1,{0x7e,0xeb},0x2a]
SEND DEBUG: "22 serialization::archive 17 0 0 0 1 126 235 42
"
Successbytes sent 49
Exit netcom_client
Successbytes received 49
RECV DEBUG: "22 serialization::archive 17 0 0 0 1 126 235 42
"
Received 1 elements at server
[false,1,{0x7e,0xeb},0x2a]
Close connection 127.0.0.1:38128
Connection Accepted : 127.0.0.1:38130
[false,1,{0x7e,0xeb},0x2a]
SEND DEBUG: "22 serialization::archive 17 0 0 0 1 126 235 42
"
Successbytes sent 49
Exit netcom_client
Successbytes received 49
RECV DEBUG: "22 serialization::archive 17 0 0 0 1 126 235 42
"
Received 1 elements at server
[false,1,{0x7e,0xeb},0x2a]
Close connection 127.0.0.1:38130
Connection Accepted : 127.0.0.1:38132
[false,1,{0x7e,0xeb},0x2a]
SEND DEBUG: "22 serialization::archive 17 0 0 0 1 126 235 42
"
Successbytes sent 49
Exit netcom_client
Successbytes received 49
RECV DEBUG: "22 serialization::archive 17 0 0 0 1 126 235 42
"
Received 1 elements at server
[false,1,{0x7e,0xeb},0x2a]
Close connection 127.0.0.1:38132
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/asio.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/vector.hpp>
#include <iostream>
#include <iomanip>
#include <mutex>

namespace {
    // very sumple hack to synchronize output to std::cout
    #define PRINT(e) { std::lock_guard<std::mutex> lk(s_mx); std::cout << e << std::endl; }
    static std::mutex s_mx;
}

namespace ba = boost::asio;
using ba::ip::tcp;

void sendData(tcp::socket& socket, std::string const& data);
std::string getData(tcp::socket& socket);

struct element {
    bool bit            = false;
    int count           = 0;
    uint64_t hashSum[2] = {};
    uint64_t idSum      = 0;

    friend std::ostream& operator<<(std::ostream& os, element const& e) {
        std::ostringstream oss;
        oss << std::showbase << std::boolalpha;

        oss << "[" << e.bit << "," 
            << std::dec << e.count << ","
            << std::hex << "{" << e.hashSum[0] << "," << e.hashSum[1] << "},"
            << e.idSum << "]";

        return os << oss.str();
    }
};

BOOST_IS_BITWISE_SERIALIZABLE(element)

namespace mocks {
    struct bloom_filter {
        bloom_filter(...) {}
        size_t size() const { return mock_data.size(); }
        void indexins_elem(element const& e, size_t i) {
            mock_data.at(i) = e;
            //// Danger: this grows the db while it is being iterated
            //assert(i <= size());
            //mock_data.insert(mock_data.begin() + i, e);
        }
        void show_elemvec() const {
            for (auto& el : mock_data) PRINT(el);
        }
        void show_elem(size_t i) const { PRINT(mock_data.at(i)); }
        element getelem(size_t i) { return mock_data.at(i); }

      private:
        std::vector<element> mock_data{
            { false, 1, { 0x7e, 0xeb }, 42 },
        };

        friend class boost::serialization::access;
        template <typename Archive> void serialize(Archive& ar, unsigned) {
            ar& mock_data;
        }
    };
}

#define USE_TEXT
#ifdef USE_TEXT
    #define ARCHIVE_ text_
    static const std::string DELIMITER("\x00", 1);
    struct safe_print {
        std::string const& data;
        friend std::ostream& operator<<(std::ostream& os, safe_print wrap) {
            return os << std::quoted(wrap.data);
        }
    };

    namespace boost { namespace serialization {
        template <typename Ar>
        void serialize(Ar& ar, element& e, unsigned) {
            ar & e.bit & e.count & e.hashSum & e.idSum;
        }
    } }
#else
    #define ARCHIVE_ binary_
    static const std::string DELIMITER("\x00\xde\xad\xbe\xef", 5);
    struct safe_print {
        std::string const& data;
        friend std::ostream& operator<<(std::ostream& os, safe_print wrap) {
            std::ostringstream oss;
            oss << std::hex << std::setfill('0');
            for (uint8_t ch : wrap.data) {
                oss << std::setw(2) << static_cast<int>(ch);
            }
            return os << oss.str();
        }
    };
#endif

template <typename T>
std::string archive(T const& data) {
    std::stringstream os;
    {
        boost::archive::BOOST_PP_CAT(ARCHIVE_, oarchive) out_archive{ os, boost::archive::no_header };
        out_archive << data;
    }
    return os.str();
}

template <typename T>
void restore(std::string const& text, T& into) {
    std::istringstream is(text);
    boost::archive::BOOST_PP_CAT(ARCHIVE_, iarchive) ia{is, boost::archive::no_header };
    ia >> into;
}

using mocks::bloom_filter;

void netcom_server(unsigned short portn) {
    ba::io_service io_service;
    tcp::acceptor acceptor_server(io_service, {tcp::v4(), portn});

    while (1) {
        tcp::socket server_socket(io_service);
        acceptor_server.accept(server_socket);
        PRINT("Connection Accepted : " << server_socket.remote_endpoint());

        bloom_filter recvd_bloomdb;
        restore(getData(server_socket), recvd_bloomdb);

        PRINT("Received " << recvd_bloomdb.size() << " elements at server");
        recvd_bloomdb.show_elemvec();
    }
}

void netcom_client(unsigned short portn, std::string serverip, bloom_filter& bloom_db) {
    ba::io_service io_service;
    tcp::socket client_socket(io_service);
    client_socket.connect({ba::ip::address::from_string(serverip), portn});

    sendData(client_socket, archive(bloom_db));
    PRINT("Exit netcom_client");
}

void sendData(tcp::socket& socket, std::string const& data) {
    PRINT("SEND DEBUG: " << safe_print{data});
    std::vector<ba::const_buffers_1> frame { 
        ba::buffer(data),
        ba::buffer(DELIMITER)
    };
    std::size_t bytes_transferred = boost::asio::write(socket, frame);
    PRINT("bytes sent " << bytes_transferred);
}

std::string getData(tcp::socket& socket) {
    std::string buffer;
    std::size_t bytes_transferred = boost::asio::read_until(socket, ba::dynamic_buffer(buffer), DELIMITER);
    PRINT("bytes received " << bytes_transferred);
    buffer.resize(bytes_transferred);
    PRINT("RECV DEBUG: " << safe_print{buffer});
    return buffer;
}

int main() {
    PRINT("For info: sizeof(element) = " << sizeof(element));
    std::thread s([] {
        bloom_filter db;
        netcom_server(6767);
    });
    std::thread c([] {
        for (int i = 0; i < 4; ++i) {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            bloom_filter db;
            netcom_client(6767, "127.0.0.1", db);
        }
    });

    s.join();
    c.join();
}
For info: sizeof(element) = 32
Connection Accepted : 127.0.0.1:38134
SEND DEBUG: "0 0 0 0 1 0 0 0 0 1 2 126 235 42
"
bytes sent 34
Exit netcom_client
bytes received 34
RECV DEBUG: "0 0 0 0 1 0 0 0 0 1 2 126 235 42
"
Received 1 elements at server
[false,1,{0x7e,0xeb},0x2a]
SEND DEBUG: "0 0 0 0 1 0 0 0 0 1 2 126 235 42
"
Connection Accepted : 127.0.0.1:38136
bytes received 34
RECV DEBUG: "0 0 0 0 1 0 0 0 0 1 2 126 235 42
"
bytes sent 34
Exit netcom_client
Received 1 elements at server
[false,1,{0x7e,0xeb},0x2a]
SEND DEBUG: "0 0 0 0 1 0 0 0 0 1 2 126 235 42
"
bytes sent 34
Exit netcom_client
Connection Accepted : 127.0.0.1:38138
bytes received 34
RECV DEBUG: "0 0 0 0 1 0 0 0 0 1 2 126 235 42
"
Received 1 elements at server
[false,1,{0x7e,0xeb},0x2a]
SEND DEBUG: "0 0 0 0 1 0 0 0 0 1 2 126 235 42
"
bytes sent 34
Exit netcom_client
Connection Accepted : 127.0.0.1:38140
bytes received 34
RECV DEBUG: "0 0 0 0 1 0 0 0 0 1 2 126 235 42
"
Received 1 elements at server
[false,1,{0x7e,0xeb},0x2a]


Share : facebook icon twitter icon
boost::archive::binary_oarchive = program crash?

boost::archive::binary_oarchive = program crash?


By : farhan
Date : March 29 2020, 07:55 AM
Any of those help I have a problem using boost::archive::binary_oarchive. When executing the program I get a program crash when instantiating the ia >> boost::serialization::make_binary_object(buffer, size). With boost::archive::text_oarchive it works... , The solution presents itself :)
code :
...
std::ofstream file("archiv.bin", ios_base::binary);
...
std::ifstream file("archiv.bin", ios_base::binary);
...
Serialization example of boost/archive/binary_woarchive.hpp and/or boost/archive/binary_wiarchive.hpp?

Serialization example of boost/archive/binary_woarchive.hpp and/or boost/archive/binary_wiarchive.hpp?


By : Noorani92
Date : March 29 2020, 07:55 AM
To fix the issue you can do It turns out that boost/archive/binary_woarchive.hpp and boost/archive/binary_wiarchive.hpp are redundant.
Instead boost/archive/binary_oarchive.hpp and boost/archive/binary_iarchive.hpp will work just fine even for class instances that contain wide character variables!
Deriving custom archive classes from boost::archive::text_oarchive_impl and boost::archive::text_iarchive_impl

Deriving custom archive classes from boost::archive::text_oarchive_impl and boost::archive::text_iarchive_impl


By : Abhinandan Guha
Date : March 29 2020, 07:55 AM
wish helps you As best I can tell its a bug in boost serialize. We'll see here.
A)
Boost: Re-using/clearing text_iarchive for de-serializing data from Asio:receive()

Boost: Re-using/clearing text_iarchive for de-serializing data from Asio:receive()


By : user3147311
Date : March 29 2020, 07:55 AM
will be helpful for those in need No there is not such a way.
The comparison to MemoryStream is broken though, because the archive is a layer above the stream.
code :
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/serialization.hpp>

#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <sstream>

namespace bar = boost::archive;
namespace bio = boost::iostreams;

struct Packet {
    int i;
    template <typename Ar> void serialize(Ar& ar, unsigned) { ar & i; }
};

namespace Reader {
    template <typename T>
    Packet deserialize(T const* data, size_t size) {
        static_assert(boost::is_pod<T>::value     , "T must be POD");
        static_assert(boost::is_integral<T>::value, "T must be integral");
        static_assert(sizeof(T) == sizeof(char)   , "T must be byte-sized");

        bio::stream<bio::array_source> stream(bio::array_source(data, size));
        bar::text_iarchive ia(stream);
        Packet result;
        ia >> result;

        return result;
    }

    template <typename T, size_t N>
    Packet deserialize(T (&arr)[N]) {
        return deserialize(arr, N);
    }

    template <typename T>
    Packet deserialize(std::vector<T> const& v) {
        return deserialize(v.data(), v.size());
    }

    template <typename T, size_t N>
    Packet deserialize(boost::array<T, N> const& a) {
        return deserialize(a.data(), a.size());
    }
}

template <typename MutableBuffer>
void serialize(Packet const& data, MutableBuffer& buf)
{
    bio::stream<bio::array_sink> s(buf.data(), buf.size());
    bar::text_oarchive ar(s);

    ar << data;
}

int main() {
    boost::array<char, 1024> arr;

    for (int i = 0; i < 100; ++i) {
        serialize(Packet { i }, arr);

        Packet roundtrip = Reader::deserialize(arr);
        assert(roundtrip.i == i);
    }
    std::cout << "Done\n";
}
boost::archive::text_iarchive constructor exception

boost::archive::text_iarchive constructor exception


By : user3172949
Date : March 29 2020, 07:55 AM
I hope this helps you . You must close the output file/archive before opening it as input.
Otherwise not the full archive will have been flushed:
code :
{
    std::ofstream ofs("file.txt");
    if (!ofs.good())
        return 1;

    boost::archive::text_oarchive oar(ofs); // no exception
    oar << numbers1;
}

{
    std::ifstream ifs("file.txt");
    if (!ifs.good())
        return 1;
    boost::archive::text_iarchive iar(ifs); // no exception!
    iar >> numbers2;
}
0 1 2 3 4 5 6 7 8 9 
Related Posts Related Posts :
  • What's wrong with my code about find the max one and the min one by vector
  • Force g++ to indicate when library is not included
  • expected unqualified-id before ‘or’ token
  • signed int vs int - is there a way to tell them apart in C++?
  • When does an asio timer go out of scope?
  • Locating objects (structs) in memory - how to?
  • GoogleTest: Accessing the Environment from a Test
  • Visual C++.NET , speed optimizations
  • Different cursor formats in IOFrameBufferShared
  • openssl versus windows capi
  • Top level window on X Window System
  • C++ pointer to const pointer
  • Is using macros to abbreviate long winded boost template names a bad practice?
  • How to detect end-of-file when using getline?
  • Converting QXmlItem to QtDomElement or similar?
  • C++ freeing static variables
  • Compiling/Debugging LZMA
  • What is the fastest way to find out the time in the windows with an accuracy of 1ms?
  • Increment order
  • C++0x atomic implementation in c++98 question about __sync_synchronize()
  • C++ - Access array (in main) from methods outside main
  • How can i stream CCTV camera to iphone from windows
  • Function that counts the number of integers in a text file?
  • "Reading" a POD preincrement result does not yield undefined behavior. Why exactly?
  • Can nullptr be emulated in gcc?
  • Swapping one widget with another in Qt
  • Fastest C++ Signal/Slot Lib without dependency
  • Isn't this an error in the book The C++ Programming Language(4 ed)?
  • Error in C++ Vector Usage: No matching member function for call to 'push_back'
  • Can someone tell me why I am unable to find the length of array using sizeof() function here?
  • How to cout a constructor?
  • printf treats *p++ differently from what happens to p
  • How to pass a constexpr array into a function
  • OpenCV building fails due to DirectX
  • How to 'backspace' using a pushbutton
  • Binary literal in condition
  • Access captured variables outside the lambda
  • Storing 4 values from each line from a txt file, into an object - C++
  • What is the most efficient way to test for duplicates in a user inputted array?
  • How to find a string in a binary file?
  • Passing variable into lambda
  • decltype(auto) function return type does not deduce && types
  • Find the unique elements of a vector C++
  • Why doesn't str != "hello" && "goodbye" work?
  • Array rotate and delete
  • Is the concept of release-sequence useful in practice?
  • Multiple spotlights in opengl doesn't work
  • The for loop isn't entered even if the initial requirement is true
  • Function is called twice from the same thread for the same object with the same call stack
  • Filling char pointer correctly
  • How Base class members gets copied in inheritance when we copy/assign derived class objects?
  • call method from a function pointer
  • Is it common to declare const pointers in C++?
  • How to check whether new threads created inside third party DLL in visual c++ application
  • I cannot convert a '2D array whit bool' to a 'void 2D array bool'(for game of life)
  • How to send variables between classes in Qt
  • What are the similarities and differences between C++'s concepts and Rust's traits?
  • Variadic templates in C++ 11 and class constructors
  • getting segmentation fault when copying arrays using std::copy
  • std::cout is decreasing CPU Usage?
  • shadow
    Privacy Policy - Terms - Contact Us © 35dp-dentalpractice.co.uk