MantisBT - VCMI
View Issue Details
0001308VCMIGUI - PreGamepublic2013-06-08 08:212022-04-11 17:38
o01eg 
Tow 
normalminoralways
closedfixed 
AMD64LinuxGentoo
0.93 
 
0001308: Second client cannot get CMapInfo at the pregame. [r3406]
The second client freezes after join but the first client shows that the second client "joins the game".
1. Start first client.
2. New game -> Multiplayer -> Host.
3. Start second client.
4. New game -> Multiplayer -> Join.
5. Connect to the server.
Establishing connection...
Found endpoints:
    0: 127.0.0.1:3030
Trying connection to 127.0.0.1:3030 (0)
Established connection with VCMI 0.93b (server)
...
(gdb) thread 14
[Switching to thread 14 (Thread 0x7fffe4c98700 (LWP 18236))]
#0 0x00007ffff689e96d in recvmsg () from /lib64/libpthread.so.0
(gdb) bt full
#0 0x00007ffff689e96d in recvmsg () from /lib64/libpthread.so.0
No symbol table info available.
#1 0x00007ffff798a1ee in recv (ec=..., flags=0, count=1, bufs=0x7fffe4c96f10,
    s=18) at /usr/include/boost-1_49/boost/asio/detail/impl/socket_ops.ipp:695
        msg = {msg_name = 0x0, msg_namelen = 0, msg_iov = 0x7fffe4c96f10,
          msg_iovlen = 1, msg_control = 0x0, msg_controllen = 0, msg_flags = 0}
        result = <optimized out>
0000002 sync_recv (ec=..., all_empty=<optimized out>, flags=0, count=1,
    bufs=0x7fffe4c96f10, state=<optimized out>, s=18)
    at /usr/include/boost-1_49/boost/asio/detail/impl/socket_ops.ipp:722
        bytes = <optimized out>
0000003 receive<boost::asio::detail::consuming_buffers<boost::asio::mutable_buffer, boost::asio::mutable_buffers_1> > (ec=..., flags=0, buffers=..., impl=...,
    this=<optimized out>)
    at /usr/include/boost-1_49/boost/asio/detail/reactive_socket_service_base.hpp:248
        bufs = {<boost::asio::detail::buffer_sequence_adapter_base> = {<No data fields>}, buffers_ = {{iov_base = 0x7fffd8fee28d, iov_len = 64411}, {
              iov_base = 0x0, iov_len = 140737347363348}, {
              iov_base = 0x7fffd8000020, iov_len = 1}, {
              iov_base = 0x7fffe4c97380, iov_len = 140737031795632}, {
              iov_base = 0x2, iov_len = 140733193388048}, {
              iov_base = 0x7fffe4c974af, iov_len = 1}, {iov_base = 0x0,
              iov_len = 140737347363348}, {iov_base = 0x2, iov_len = 2}, {
              iov_base = 0x7fffe4c973d0, iov_len = 140737031795712}, {
              iov_base = 0x0, iov_len = 140733193388048}, {
              iov_base = 0x7fffe4c974ec, iov_len = 2}, {
              iov_base = 0x7fffe4c97400, iov_len = 140737031795760}, {
              iov_base = 0xe4c97430, iov_len = 140733193388048}, {
              iov_base = 0x7fffd8535e19, iov_len = 1}, {
              iov_base = 0x4fa890 <pthread_cancel@plt>,
              iov_len = 140736821735936}, {iov_base = 0x9b2eb0 <logNetwork>,
              iov_len = 0}, {iov_base = 0x7fffd8458b40,
              iov_len = 140736821735936}, {iov_base = 0x9b2eb0 <logNetwork>,
              iov_len = 0}, {iov_base = 0x7fffd8458b40,
              iov_len = 140737347330800}, {iov_base = 0x7ffff4760520,
              iov_len = 140737031794944}, {iov_base = 0x7fff00000000,
              iov_len = 140737031794912}, {iov_base = 0x7fffd8458cb0,
              iov_len = 140736821824656}, {iov_base = 0x12d841e878,
              iov_len = 140736821996112}, {iov_base = 0x20,
              iov_len = 25769803777}, {iov_base = 0x0, iov_len = 0}, {
              iov_base = 0x0, iov_len = 0}, {iov_base = 0xe9e938,
              iov_len = 140736822909416}, {iov_base = 0x100007fd60b0002,
              iov_len = 0}, {iov_base = 0x0, iov_len = 140733193388032}, {
              iov_base = 0x7fffd847a230, iov_len = 0}, {iov_base = 0x0,
              iov_len = 140737031795368}, {iov_base = 0x0, iov_len = 0}, {
              iov_base = 0x0, iov_len = 140737343954912}, {iov_base = 0x0,
              iov_len = 0}, {iov_base = 0x0, iov_len = 0}, {
              iov_base = 0x7fffd841e970, iov_len = 140736821824768}, {
              iov_base = 0x0, iov_len = 4360000}, {iov_base = 0x500000000,
              iov_len = 4294972177}, {iov_base = 0x7fffe4c972a0,
              iov_len = 140737354130688}, {iov_base = 0x9c84b0, iov_len = 3}, {
              iov_base = 0x1, iov_len = 1}, {iov_base = 0x7fffe4c9745f,
              iov_len = 1}, {iov_base = 0x1, iov_len = 140737031795807}, {
              iov_base = 0x1, iov_len = 140737031795120}, {iov_base = 0x10000,
              iov_len = 140737354129832}, {iov_base = 0x0, iov_len = 0}, {
              iov_base = 0x7fffe4c96d90, iov_len = 1}, {iov_base = 0x0,
              iov_len = 0}, {iov_base = 0x0, iov_len = 140737351925652}, {
              iov_base = 0x100ea0330, iov_len = 140737031795376}, {
              iov_base = 0x7fffe4c972a0, iov_len = 140736821824320}, {
              iov_base = 0x7fffd8443200, iov_len = 69575}, {
              iov_base = 0x7fffd8000020, iov_len = 69600}, {iov_base = 0x0,
              iov_len = 140736822729968}, {iov_base = 0x7fffe4c97bb0,
              iov_len = 140737283058884}, {iov_base = 0x10ff0, iov_len = 1}, {
              iov_base = 0x7fff00000000, iov_len = 140737338810520}, {
              iov_base = 0x7fffd8000088, iov_len = 140736817266808}, {
              iov_base = 0x7fffd8478260, iov_len = 6812369}, {
              iov_base = 0x10fe0, iov_len = 519695740614}, {
              iov_base = 0x10ff0, iov_len = 1087}, {iov_base = 0x11010,
              iov_len = 135}, {iov_base = 0x10, iov_len = 2}, {iov_base = 0x0,
              iov_len = 4874787885311}}, count_ = 1,
          total_buffer_size_ = 64411}
0000004 receive<boost::asio::detail::consuming_buffers<boost::asio::mutable_buffer, boost::asio::mutable_buffers_1> > (flags=0, impl=..., ec=..., buffers=...,
    this=<optimized out>)
    at /usr/include/boost-1_49/boost/asio/stream_socket_service.hpp:308
No locals.
0000005 read_some<boost::asio::detail::consuming_buffers<boost::asio::mutable_buffer, boost::asio::mutable_buffers_1> > (ec=..., buffers=..., this=0x7fffd8443200)
    at /usr/include/boost-1_49/boost/asio/basic_stream_socket.hpp:740
No locals.
0000006 boost::asio::read<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1, boost::asio::detail::transfer_all_t> (s=..., buffers=...,
    completion_condition=..., ec=...)
    at /usr/include/boost-1_49/boost/asio/impl/read.hpp:50
        tmp = {buffers_ = {<boost::asio::mutable_buffer> = {
              data_ = 0x7fffd8fedd28, size_ = 65792}, <No data fields>},
          at_end_ = false, first_ = {data_ = 0x7fffd8fee28d, size_ = 64411},
          begin_remainder_ = 0x7fffe4c97330, max_size_ = 65536}
        total_transferred = <optimized out>
0000007 0x00007ffff797c1c4 in read<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::mutable_buffers_1> (buffers=..., s=...)
    at /usr/include/boost-1_49/boost/asio/impl/read.hpp:63
        ec = {m_val = 0, m_cat = 0x7ffff7162098}
        bytes_transferred = <optimized out>
0000008 CConnection::read (this=0x7fffd8458b40, data=<optimized out>,
    size=<optimized out>) at /mnt/another/tmp/vcmi/lib/Connection.cpp:164
        ret = <optimized out>
0000009 0x00000000005d44c6 in CISer<CConnection>::loadSerializable (
    this=0x7fffd8458b40, data=
    "\000\000\000\000\034\000\000\000\t\000\000\000Arrogance\334\000\000\000Once, centuries ago, the world was at peace. Four cultures lived in harmony and freely associated with each other. Then you came into power and realized things would be bette"...) at /mnt/another/tmp/vcmi/client/../lib/Connection.h:1180
        length = 65792
0000010 0x0000000000683404 in invoke (data=
    "\000\000\000\000\034\000\000\000\t\000\000\000Arrogance\334\000\000\000Once, centuries ago, the world was at peace. Four cultures lived in harmony and freely associated with each other. Then you came into power and realized things would be bette"..., s=...)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:230
No locals.
0000011 load<std::basic_string<char> > (data=
    "\000\000\000\000\034\000\000\000\t\000\000\000Arrogance\334\000\000\000Once, centuries ago, the world was at peace. Four cultures lived in harmony and freely associated with each other. Then you came into power and realized things would be bette"..., this=0x7fffd8458b40)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:935
No locals.
0000012 operator>><std::basic_string<char> > (t=
    "\000\000\000\000\034\000\000\000\t\000\000\000Arrogance\334\000\000\000Once, centuries ago, the world was at peace. Four cultures lived in harmony and freely associated with each other. Then you came into power and realized things would be bette"..., this=0x7fffd8458b40)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:890
No locals.
0000013 operator&<std::basic_string<char> > (t=
    "\000\000\000\000\034\000\000\000\t\000\000\000Arrogance\334\000\000\000Once, centuries ago, the world was at peace. Four cultures lived in harmony and freely associated with each other. Then you came into power and realized things would be bette"..., this=0x7fffd8458b40)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:897
No locals.
0000014 serialize<CISer<CConnection> > (Version=<optimized out>, h=...,
    this=0x7fffd8478250)
    at /mnt/another/tmp/vcmi/client/../lib/mapping/CMapInfo.h:42
No locals.
0000015 loadSerializableBySerializeCall<CMapInfo const> (data=...,
    this=0x7fffd8458b40)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:960
        hlp = @0x7fffd8478250: {mapHeader = std::shared_ptr (empty) 0x0,
          campaignHeader = std::shared_ptr (empty) 0x0, scenarioOpts = 0x0,
          fileURI =
    "\000\000\000\000\034\000\000\000\t\000\000\000Arrogance\334\000\000\000Once, centuries ago, the world was at peace. Four cultures lived in harmony and freely associated with each other. Then you came into power and realized things would be bette"..., date = "", playerAmnt = 0, humanPlayers = 0,
          actualHumanPlayers = 0, isRandomMap = false}
0000016 loadSerializable<CMapInfo const> (data=..., this=0x7fffd8458b40)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:967
No locals.
0000017 invoke (s=..., data=...)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:230
No locals.
0000018 load<CMapInfo const> (data=..., this=0x7fffd8458b40)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:935
No locals.
0000019 operator>><const CMapInfo> (t=..., this=0x7fffd8458b40)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:890
No locals.
0000020 CISer<CConnection>::loadPointerHlp<CMapInfo const*> (this=0x7fffd8458b40,
    tid=0, data=@0x7fffe4c97b18: 0x7fffd8478250, pid=<optimized out>)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:1041
No locals.
0000021 0x000000000068360e in CISer<CConnection>::loadPointer<CMapInfo const*> (
    this=0x7fffd8458b40, data=@0x7fffe4c97b18: 0x7fffd8478250)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:1028
        hlp = 1 '\001'
        pid = 4294967295
        tid = <optimized out>
0000022 0x000000000066853b in invoke (s=..., data=@0x7fffe4c97b18: 0x7fffd8478250)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:206
No locals.
0000023 load<CMapInfo const*> (data=@0x7fffe4c97b18: 0x7fffd8478250,
    this=<optimized out>)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:935
No locals.
0000024 operator>><const CMapInfo*> (t=@0x7fffe4c97b18: 0x7fffd8478250,
    this=<optimized out>)
    at /mnt/another/tmp/vcmi/client/../lib/Connection.h:890
No locals.
0000025 CSelectionScreen::CSelectionScreen (this=0x7fffd8535c80,
    Type=<optimized out>, MultiPlayer=<optimized out>, Names=<optimized out>,
    Address="127.0.0.1", Port="3030")
    at /mnt/another/tmp/vcmi/client/CPreGame.cpp:723
        map = <optimized out>
        obj__i1 = {previousCapture = false, prevActions = 63 '?'}
        obj(int) = {myObj = 0x7fffd8535c80}
        backName = "SCNRBACK.DEF"
        network = <optimized out>
        sh = 0x0
0000026 0x0000000000668caa in CSimpleJoinScreen::enterSelectionScreen (
    this=<optimized out>) at /mnt/another/tmp/vcmi/client/CPreGame.cpp:4187
        textAddress = "127.0.0.1"
        textPort = "3030"
0000027 0x000000000055372b in operator() (this=0x7fffd85619a0)
    at /usr/include/boost-1_49/boost/function/function_template.hpp:760
No locals.
0000028 CFunctionList<void ()>::operator()() const (this=<optimized out>)
    at /mnt/another/tmp/vcmi/client/gui/../FunctionList.h:62
        i = <optimized out>
        funcs2 = std::vector of length 1, capacity 1 = {
          {<boost::function0<void>> = {<boost::function_base> = {
                vtable = 0x72e5d1, functor = {
                  obj_ptr = 0x668c40 <CSimpleJoinScreen::enterSelectionScreen()>, type = {type = 0x668c40 <CSimpleJoinScreen::enterSelectionScreen()>,
                    const_qualified = false, volatile_qualified = false},
                  func_ptr = 0x668c40 <CSimpleJoinScreen::enterSelectionScreen()>, bound_memfunc_ptr = {memfunc_ptr = (void (boost::detail::function::X::*)(
    boost::detail::function::X * const,
    int)) 0x668c40 <CSimpleJoinScreen::enterSelectionScreen()>,
                    obj_ptr = 0x7fffd85535a0}, obj_ref = {
                    obj_ptr = 0x668c40 <CSimpleJoinScreen::enterSelectionScreen()>, is_const_qualified = false, is_volatile_qualified = false},
                  data = 64 '@'}}, static args = <optimized out>,
              static arity = <optimized out>}, <No data fields>}}
0000029 0x0000000000542234 in CGuiHandler::handleEvent (this=0x9b3ca0 <GH>,
    sEvent=0x7fffe4c97cc0)
    at /mnt/another/tmp/vcmi/client/gui/CGuiHandler.cpp:284
        i =
        hlp = std::list = {[0] = 0x7fffd84d4030, [1] = 0x7fffd8539140,
          [2] = 0x7fffd856cd78, [3] = 0x7fffd8535d28}
        prev = true
0000030 0x0000000000542653 in CGuiHandler::handleEvents (this=0x9b3ca0 <GH>)
    at /mnt/another/tmp/vcmi/client/gui/CGuiHandler.cpp:177
        ev = {type = 6 '\006', active = {type = 6 '\006', gain = 0 '\000',
            state = 1 '\001'}, key = {type = 6 '\006', which = 0 '\000',
            state = 1 '\001', keysym = {scancode = 191 '\277',
              sym = SDLK_UNKNOWN, mod = KMOD_NONE, unicode = 0}}, motion = {
            type = 6 '\006', which = 0 '\000', state = 1 '\001', x = 447,
            y = 431, xrel = 0, yrel = 0}, button = {type = 6 '\006',
            which = 0 '\000', button = 1 '\001', state = 0 '\000', x = 447,
            y = 431}, jaxis = {type = 6 '\006', which = 0 '\000',
            axis = 1 '\001', value = 447}, jball = {type = 6 '\006',
            which = 0 '\000', ball = 1 '\001', xrel = 447, yrel = 431},
          jhat = {type = 6 '\006', which = 0 '\000', hat = 1 '\001',
            value = 0 '\000'}, jbutton = {type = 6 '\006', which = 0 '\000',
            button = 1 '\001', state = 0 '\000'}, resize = {type = 6 '\006',
            w = 28246463, h = 0}, expose = {type = 6 '\006'}, quit = {
            type = 6 '\006'}, user = {type = 6 '\006', code = 28246463,
            data1 = 0x0, data2 = 0x0}, syswm = {type = 6 '\006', msg = 0x0}}
        lock = {m = 0x9b3be0 <eventsM>, is_locked = true}
0000031 0x0000000000648527 in CGPreGame::update (this=0xf19a40)
    at /mnt/another/tmp/vcmi/client/CPreGame.cpp:521
        lock = {m = 0x9e9ec0, is_locked = true}
0000032 0x00000000005414e9 in CGuiHandler::run (this=0x9b3ca0 <GH>)
    at /mnt/another/tmp/vcmi/client/gui/CGuiHandler.cpp:385
No locals.
0000033 0x00007ffff6d522a4 in ?? ()
   from /usr/lib64/libboost_thread-mt-1_49.so.1.49.0
No symbol table info available.
0000034 0x00007ffff6896d96 in start_thread () from /lib64/libpthread.so.0
No symbol table info available.
0000035 0x00007ffff3ca546d in clone () from /lib64/libc.so.6
No symbol table info available.
No tags attached.
zip vcmi.zip (3,126) 2013-06-08 08:21
https://bugs.vcmi.eu/file_download.php?file_id=1359&type=bug
Issue History
2013-06-08 08:21o01egNew Issue
2013-06-08 08:21o01egStatusnew => assigned
2013-06-08 08:21o01egAssigned To => Tow
2013-06-08 08:21o01egFile Added: vcmi.zip
2013-06-24 09:34o01egNote Added: 0003724
2013-06-24 11:00o01egNote Edited: 0003724bug_revision_view_page.php?bugnote_id=3724#r2326
2013-06-24 11:10o01egNote Added: 0003725
2013-06-24 18:48o01egNote Added: 0003726
2013-06-24 20:02IvanNote Added: 0003727
2013-06-24 20:06o01egNote Added: 0003728
2013-06-24 20:10o01egNote Added: 0003729
2013-07-04 06:54o01egNote Added: 0003734
2013-07-04 06:54o01egStatusassigned => feedback
2013-07-04 12:07TowNote Added: 0003735
2013-07-04 12:07TowStatusfeedback => resolved
2013-07-04 12:07TowResolutionopen => fixed
2013-07-04 12:07TowNote Edited: 0003735bug_revision_view_page.php?bugnote_id=3735#r2330
2022-04-11 17:38PovelitelStatusresolved => closed

Notes
(0003724)
o01eg   
2013-06-24 09:34   
(edited on: 2013-06-24 11:00)
I separated lines in CMapInfo::serialize and found that the client stucks at fileURI;

(0003725)
o01eg   
2013-06-24 11:10   
I breakpoint a client and server at "h & fileURI" so found that:

client:
Breakpoint 1, serialize<CISer<CConnection> > (Version=<optimized out>, h=..., this=0x7fffd84728c0)
    at /mnt/another/tmp/vcmi/client/../lib/mapping/CMapInfo.h:45
45 h & fileURI;
(gdb) p fileURI
$1 = ""
(gdb) l
40 template <typename Handler> void serialize(Handler &h, const int Version)
41 {
42 h & mapHeader;
43 h & campaignHeader;
44 h & scenarioOpts;
45 h & fileURI;
46 h & date;
47 h & playerAmnt;
48 h & humanPlayers;
49 h & actualHumanPlayers & isRandomMap;
(gdb) p mapHeader
$2 = std::shared_ptr (empty) 0x0
(gdb) p campaignHeader
$3 = std::shared_ptr (empty) 0x0
(gdb) p scenarioOpts
$4 = (StartInfo *) 0x0

server:
Breakpoint 1, serialize<COSer<CConnection> > (Version=741, h=...,
    this=0x7fc4a40009a0)
    at /mnt/another/tmp/vcmi/server/../lib/mapping/CMapInfo.h:45
45 h & fileURI;
(gdb) p fileURI
$1 = "MAPS/ARROGANCE"
(gdb) l
40 template <typename Handler> void serialize(Handler &h, const int Version)
41 {
42 h & mapHeader;
43 h & campaignHeader;
44 h & scenarioOpts;
45 h & fileURI;
46 h & date;
47 h & playerAmnt;
48 h & humanPlayers;
49 h & actualHumanPlayers & isRandomMap;
(gdb) p mapHeader
$2 = std::shared_ptr (count 2) 0x7fc4a4000a20
(gdb) p campaignHeader
$3 = std::shared_ptr (empty) 0x0
(gdb) p scenarioOpts
$4 = (StartInfo *) 0x0

It looks like error at std::shared_ptr transferring.
(0003726)
o01eg   
2013-06-24 18:48   
I've found source of the bug. There is difference between savePointer and loadPointer so client wait for 2 byte of tid at lib/Connection.h:1027 but server send 4 byte of pid at lib/Connection.h:638. smartPointerSerialization is false at client but is true at server.
(0003727)
Ivan   
2013-06-24 20:02   
^ on std::smart_ptr

IIRC you can change code to use std::unique_ptr instead. Only reason why smart_ptr is in use here is due to gcc-4.5 bug. And this gcc version is unlikely to be supported for long.

Don't know if smartPointerSerialization affects unique_ptr though.
(0003728)
o01eg   
2013-06-24 20:06   
I've alredy fixed this bug. The client calls CConnecton::enterPregameConnectionMode before reading CMapInfo but the server does it after:

Index: server/CVCMIServer.cpp
===================================================================
--- server/CVCMIServer.cpp (revision 3423)
+++ server/CVCMIServer.cpp (working copy)
@@ -207,10 +207,10 @@
     initConnection(pc);
     upcomingConnection = NULL;
 
+ startListeningThread(pc);
+
     *pc << (ui8)pc->connectionID << curmap;
 
- startListeningThread(pc);
-
     announceTxt(pc->name + " joins the game");
     PlayerJoined *pj = new PlayerJoined();
     pj->playerName = pc->name;
(0003729)
o01eg   
2013-06-24 20:10   
It doesn't depend on type of a pointer because data chooses at savePointer/loadPointer that use even for any type of pointer.
(0003734)
o01eg   
2013-07-04 06:54   
Fixed at 3436
(0003735)
Tow   
2013-07-04 12:07   
Right, thank you.

One more note on the topic: smartPointerSerialization is not related to smart pointers (as in shared_ptr). It merely does that:

//smartPointerSerialization is true

A *a1 = new A();
A *a2 = a1;

out << a1 << a2; //serializes object only for a1 serialization, a2 sends only info that it points to the same thing as a1

//on the other side of connection
in >> a1 >> a2; //a1 deserialization allocates object and sets its fields, a2 is set to a1


When smartPointerSerialization is false, sending pointer always sends its full state and receiving pointer always allocates new object for it.