簡體   English   中英

C++ - 分段錯誤。 - malloc.c: 沒有那個文件或目錄

[英]C++ - Segmentation fault. - malloc.c: No such file or directory

這是我的 GDB 堆棧跟蹤:

Program received signal SIGSEGV, Segmentation fault.
__GI___libc_free (mem=0x4645444342414746) at malloc.c:3102
3102    malloc.c: No such file or directory.
(gdb) bt
#0  __GI___libc_free (mem=0x4645444342414746) at malloc.c:3102
#1  0x00005555555b7e22 in __gnu_cxx::new_allocator<char>::deallocate (this=0x55555562d0c0, __p=0x4645444342414746 <error: Cannot access memory at address 0x4645444342414746>) at /usr/include/c++/9/ext/new_allocator.h:128
#2  0x00005555555b51ec in std::allocator_traits<std::allocator<char> >::deallocate (__a=..., __p=0x4645444342414746 <error: Cannot access memory at address 0x4645444342414746>, __n=18087021261120207611) at /usr/include/c++/9/bits/alloc_traits.h:470
#3  0x00007ffff7f93a72 in std::_Vector_base<char, std::allocator<char> >::_M_deallocate (this=0x55555562d0c0, __p=0x4645444342414746 <error: Cannot access memory at address 0x4645444342414746>, __n=18087021261120207611) at /usr/include/c++/9/bits/stl_vector.h:351
#4  0x00007ffff7f9275a in std::_Vector_base<char, std::allocator<char> >::~_Vector_base (this=0x55555562d0c0, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/stl_vector.h:332
#5  0x00007ffff7f9175f in std::vector<char, std::allocator<char> >::~vector (this=0x55555562d0c0 = {...}, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/stl_vector.h:680
#6  0x00007ffff7f97282 in boost::asio::basic_streambuf<std::allocator<char> >::~basic_streambuf (this=0x55555562d078, __in_chrg=<optimized out>) at /usr/include/boost/asio/basic_streambuf.hpp:111
#7  0x00007ffff7f90652 in Packet::~Packet (this=0x55555562d068, __in_chrg=<optimized out>) at /home/armegon/Vibranium-Core/Source/Common/Server/Packet.h:16
#8  0x00007ffff7f9816c in Vibranium::Client::~Client (this=0x55555562d020, __in_chrg=<optimized out>) at /home/armegon/Vibranium-Core/Source/Common/Server/Client.h:19
#9  0x00007ffff7f981ac in __gnu_cxx::new_allocator<Vibranium::Client>::destroy<Vibranium::Client> (this=0x55555562d020, __p=0x55555562d020) at /usr/include/c++/9/ext/new_allocator.h:153
#10 0x00007ffff7f97c05 in std::allocator_traits<std::allocator<Vibranium::Client> >::destroy<Vibranium::Client> (__a=..., __p=0x55555562d020) at /usr/include/c++/9/bits/alloc_traits.h:497
#11 0x00007ffff7f9745b in std::_Sp_counted_ptr_inplace<Vibranium::Client, std::allocator<Vibranium::Client>, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x55555562d010) at /usr/include/c++/9/bits/shared_ptr_base.h:557
#12 0x00005555555b373c in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x55555562d010) at /usr/include/c++/9/bits/shared_ptr_base.h:155
#13 0x00005555555b1575 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x7fffffffdfe8, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr_base.h:730
#14 0x00007ffff7f90706 in std::__shared_ptr<Vibranium::Client, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x7fffffffdfe0, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr_base.h:1169
#15 0x00007ffff7f90726 in std::shared_ptr<Vibranium::Client>::~shared_ptr (this=0x7fffffffdfe0 = {...}, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr.h:103
#16 0x00007ffff7f98e6e in Vibranium::Client::<lambda(boost::system::error_code, std::size_t)>::~<lambda>(void) (this=0x7fffffffdfd8, __in_chrg=<optimized out>) at /home/armegon/Vibranium-Core/Source/Common/Server/Client.cpp:35
#17 0x00007ffff7f997f2 in boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, boost::asio::mutable_buffers_1, const boost::asio::mutable_buffer*, boost::asio::detail::transfer_all_t, Vibranium::Client::read_size()::<lambda(boost::system::error_code, std::size_t)> >::~read_op(void) (this=0x7fffffffdfb0, __in_chrg=<optimized out>) at /usr/include/boost/asio/impl/read.hpp:317
#18 0x00007ffff7f9aa38 in boost::asio::detail::binder2<boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, boost::asio::mutable_buffers_1, const boost::asio::mutable_buffer*, boost::asio::detail::transfer_all_t, Vibranium::Client::read_size()::<lambda(boost::system::error_code, std::size_t)> >, boost::system::error_code, long unsigned int>::~binder2(void) (this=0x7fffffffdfb0, __in_chrg=<optimized out>) at /usr/include/boost/asio/detail/bind_handler.hpp:127
#19 0x00007ffff7f9ab87 in boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, boost::asio::detail::read_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::executor>, boost::asio::mutable_buffers_1, const boost::asio::mutable_buffer*, boost::asio::detail::transfer_all_t, Vibranium::Client::read_size()::<lambda(boost::system::error_code, std::size_t)> >, boost::asio::detail::io_object_executor<boost::asio::executor> >::do_complete(void *, boost::asio::detail::operation *, const boost::system::error_code &, std::size_t) (owner=0x55555563e380, base=0x555555631a60) at /usr/include/boost/asio/detail/reactive_socket_recv_op.hpp:114
#20 0x00005555555aa984 in boost::asio::detail::scheduler_operation::complete (this=0x555555631a60, owner=0x55555563e380, ec=..., bytes_transferred=0) at /usr/include/boost/asio/detail/scheduler_operation.hpp:40
#21 0x00005555555af30e in boost::asio::detail::scheduler::do_run_one (this=0x55555563e380, lock=..., this_thread=..., ec=...) at /usr/include/boost/asio/detail/impl/scheduler.ipp:447
#22 0x00005555555aed1a in boost::asio::detail::scheduler::run (this=0x55555563e380, ec=...) at /usr/include/boost/asio/detail/impl/scheduler.ipp:200
#23 0x00005555555af86c in boost::asio::io_context::run (this=0x7fffffffe1f0) at /usr/include/boost/asio/impl/io_context.ipp:63
#24 0x00005555555a7795 in main () at /home/armegon/Vibranium-Core/Source/Core/AuthServer/AuthServer.cpp:34
#25 0x00007ffff74cd0b3 in __libc_start_main (main=0x5555555a74e8 <main()>, argc=1, argv=0x7fffffffe518, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe508) at ../csu/libc-start.c:308
#26 0x00005555555a740e in _start ()

在這里,我僅提供堆棧跟蹤中提到的代碼:

Packet.h

class Packet { //Packet.h 16
public:
    Packet()
    {
    }
    static const int header_size_in_bytes = 4;
    uint8_t size[header_size_in_bytes] = {0};
    size_t body_size{0};
    boost::asio::streambuf body_;
    void PreparePacket(ServerOpcode serverOpcode, std::string message);
};


#endif //VIBRANIUM_CORE_PACKET_H

Packet.cpp

void Packet::PreparePacket(ServerOpcode serverOpcode, std::string message) {
}

Client.h

using boost::asio::ip::tcp;

namespace Vibranium{
    class Client: public std::enable_shared_from_this<Client> // Client.h 19
    {
    public:
        Client(tcp::socket socket)
        : socket(std::move(socket))
        {
        }
        void start();
        int connectionId;
        tcp::socket socket;
        void Send(ServerOpcode serverOpcode, const std::string& message);
        void Disconnect() const;
    private:
        void read_size();
        void read_message();
        Packet _packet;
    };
}
#endif //VIBRANIUM_CORE_CLIENT_H

Client.cpp

using namespace Vibranium;

void Vibranium::Client::start() {
    read_size();
}

void Vibranium::Client::Send(ServerOpcode serverOpcode, const std::string& message) {
}

void Vibranium::Client::read_size() {
    auto self(shared_from_this());
    boost::asio::async_read(socket,
    boost::asio::buffer(&_packet.size, _packet.header_size_in_bytes),
    [this, self](boost::system::error_code ec,std::size_t bytes_transferred) //Client.cpp 35
    {
        if ((boost::asio::error::eof == ec) || (boost::asio::error::connection_reset == ec))
        {
            Disconnect();
        }
        else
        {
            _packet.body_size = static_cast<int>(_packet.size[0]);
            read_message();
        }
    });
}


void Vibranium::Client::read_message() {
    auto self(shared_from_this());
    _packet.body_.prepare(_packet.body_size);
    boost::asio::async_read(socket,
    boost::asio::buffer(&_packet.body_, _packet.body_size),
    [this, self](boost::system::error_code ec,std::size_t bytes_transferred)
    {
        if ((boost::asio::error::eof == ec) || (boost::asio::error::connection_reset == ec))
        {
            Disconnect();
        }
        else
        {

            const char *HEADER = "ABVG";
            const char* buffIdentifier = flatbuffers::GetBufferIdentifier(&_packet.body_);
            bool hasIdentifier = flatbuffers::BufferHasIdentifier(&_packet.body_,HEADER);

            std::cout << "Builder Identifier" << buffIdentifier << std::endl;
            std::cout << "Builder Has Identifier" << hasIdentifier << std::endl;
            auto ac = GetAccountRole_Packet(&_packet.body_);
            std::cout << "ID" << ac->id() << std::endl;
            std::cout << "NAME:" << ac->name()->c_str() << std::endl;
            read_size();
        }
    });
}


void Vibranium::Client::Disconnect() const {
    Logger::Log("Disconnected ID: " + std::__cxx11::to_string(this->connectionId), Logger::Error, true);
    for (int i = 0; i < Vibranium::Server::Clients.size(); ++i) {
        if(Vibranium::Server::Clients[i]->connectionId == this->connectionId)
            Vibranium::Server::Clients.erase(Vibranium::Server::Clients.begin() + i);
    }
}

AuthServer.cpp :

#include "Config.h"
#include "Database/MySQLConnection.h"
#include "Implementation/LoginDatabase.h"
#include "Banner.h"
#include "Server/Server.h"
#include <boost/asio.hpp>

using boost::asio::ip::tcp;
using namespace std;
using namespace Vibranium;

int main() {
    //Don't mind Logger::FatalError it's just for coloring!
    Banner::Show(Logger::Error,"AuthServer");
    Config config("AuthServer");
    std::string defaultPort = "8080";
    MySQLConnectionInfo mySqlConnectionInfo(config, "LoginDatabaseInfo");
    LoginDatabaseConnection loginDatabaseConnection(mySqlConnectionInfo);
    loginDatabaseConnection.LoadDatabase();

    try
    {
        boost::asio::io_service io_service;
        Server s(io_service, std::stoi(config.GetConfigValue("AuthServerPort", defaultPort)));
        io_service.run(); // <---- LINE 34 is HERE 
    }
    catch (std::exception& e)
    {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
}

我對 C++ 和 GDB 有點陌生。 我想了解是什么導致了這次崩潰。 我的錯誤在哪里,我該如何解決?

PS 這可能很重要,所以我添加了如何向服務器發送消息,然后發生崩潰:

flatbuffers::FlatBufferBuilder builder;
std::string str = "ABCDEFGABCDEFGABCDEFGABCDEFGABCDEFG I AM HERE!";
auto name = builder.CreateString(str);
auto accountRole = Vibranium::CreateAccountRole_Packet(builder,5,name);
const char *HEADER = "ABVG";
builder.FinishSizePrefixed(accountRole, HEADER);
size_t size = builder.GetSize();
uint8_t *buf = builder.GetBufferPointer();
const char* buffIdentifier = flatbuffers::GetBufferIdentifier(buf,true);
const uint8_t prefixSize = flatbuffers::GetPrefixedSize(buf);
bool hasIdentifier = flatbuffers::BufferHasIdentifier(buf,HEADER);

boost::asio::write(s, boost::asio::buffer(buf,size));

收到消息時的服務器輸出:

Builder IdentifierABV
Builder Has Identifier1
ID5
NAME:ABCDEFGABCDEFGABCDEFGABCDEFGABCDEFG I AM HERE!

看看Builder IdentifierABV它實際上已經減少了它的長度。 它必須是Builder IdentifierABVG <--

正如@user4581301 和@john 所建議的那樣,我進行了一些更改以使其正常工作。

我變了:

boost::asio::streambuf body_;

到:

std::vector<size_t>* body_;

read_message()看起來像這樣:

void Vibranium::Client::read_message() {
    auto self(shared_from_this());
    (*_packet.body_).resize(_packet.body_size);
    boost::asio::async_read(socket,
    boost::asio::buffer(&_packet.body_, _packet.body_size),
    [this, self](boost::system::error_code ec,std::size_t bytes_transferred)
    {
        if ((boost::asio::error::eof == ec) || (boost::asio::error::connection_reset == ec))
        {
            Disconnect();
        }
        else
        {

            const char *HEADER = "ABVG";
            const char* buffIdentifier = flatbuffers::GetBufferIdentifier(&_packet.body_);
            bool hasIdentifier = flatbuffers::BufferHasIdentifier(&_packet.body_,HEADER);

            std::cout << "Builder Identifier" << buffIdentifier << std::endl;
            std::cout << "Builder Has Identifier" << hasIdentifier << std::endl;
            auto ac = GetAccountRole_Packet(&_packet.body_);
            std::cout << "ID" << ac->id() << std::endl;
            std::cout << "NAME:" << ac->name()->c_str() << std::endl;
            read_size();
        }
    });
}
boost::asio::streambuf body_;

Body 不是 POD 或此類的連續數組。 因此asio::buffer(&body_, ...)是非法的(調用UB )。

簡單地使用body_作為給定(接受復合操作,例如boost::asio::async_readhttps boost::asio::async_read )。

您當然可以使用另一種緩沖區類型,但不需要像您自己的答案那樣進行額外的動態分配級別:

std::vector<size_t> body_;

// ...
body_resize(XXX);

// ...
     asio::buffer(body_),

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM