python - 为什么 "stack smashing detected"一旦 ZeroMQ C++ 客户端针对 python 服务器运行?

标签 python c++ cmake stack zeromq

我正在尝试学习如何使用 ZeroMQ 库在客户端和服务器之间交换数据(一个简单的“你好”)。


python client - python server implementation works

我成功地用 python 创建了一个客户端和一个服务器,我可以交换数据。


C++ client - python server implementation not

下一步是用 C++ 创建一个客户端,用 python 创建一个服务器。我这样做过:

C++ 客户端,client_cpp.cpp:

   #include <zmq.hpp>
   #include <string>
   #include <iostream>


   int main ()
   {
      zmq::context_t context (1);
      zmq::socket_t socket (context, ZMQ_REQ);
      std::cout << "Connecting to hello world server…" << std::endl;
      socket.connect ("tcp://localhost:5555");
      std::string message = "hello";
      zmq::message_t request (message.size());
      memcpy (request.data (), (message.c_str()), (message.size()));
      socket.send (request);

      return 0;
   }

我使用 CMake 和以下 CMakeLists.txt 编译了它:

   cmake_minimum_required(VERSION 2.8)
   project(ZmqProject)

   # This will file libzmq.so file from /usr/local/lib
   FIND_FILE(ZMQLIB libzmq.so /usr/local/lib)
   IF(NOT ZMQLIB)
   MESSAGE(SEND_ERROR "Ah.. Cannot find library libzmq.so.")
   ENDIF(NOT ZMQLIB)

   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
   set(SOURCE_FILES client_cpp.cpp)

   add_executable(ZmqProject ${SOURCE_FILES})
   # The following line will link with libzmq.so
   TARGET_LINK_LIBRARIES( ZmqProject ${ZMQLIB})

然后,python 服务器 server_python.py 如下:

   # -*- coding: utf-8 -*-
   import time
   import zmq

   context = zmq.Context()
   socket = context.socket(zmq.REP)
   socket.bind("tcp://*:5555")
   message = socket.recv()
   print("Received data: %s" % message)

C++的客户端执行这些程序,出现这种错误:

   *** stack smashing detected ***: ./ZmqProject terminated
   Aborted (core dumped)

而且我在 python 服务器上什么也收不到。

Q1:为什么,哪里出了问题?


EDIT 1 - 通过 valgrind 运行客户端这是输出,也许有用:

valgrind --leak-check=full -v ./ZmqProject 
==12291== Memcheck, a memory error detector
==12291== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==12291== Using Valgrind-3.10.1 and LibVEX; rerun with -h for    copyright     info
==12291== Command: ./ZmqProject
==12291== 
--12291-- Valgrind options:
--12291--    --leak-check=full
--12291--    -v
--12291-- Contents of /proc/version:
--12291--   Linux version 3.19.0-59-generic (buildd@lgw01-39) (gcc    version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #66~14.04.1-Ubuntu SMP Fri May 13     17:27:10 UTC 2016
--12291-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-rdtscp-sse3-avx
--12291-- Page sizes: currently 4096, max supported 4096
--12291-- Valgrind library directory: /usr/lib/valgrind
--12291-- Reading syms from /home/fds/Scrivania/ClientProgram/build     /ZmqProject
--12291-- Reading syms from /lib/x86_64-linux-gnu/ld-2.19.so
--12291--   Considering /lib/x86_64-linux-gnu/ld-2.19.so ..
--12291--   .. CRC mismatch (computed 46abf574 wanted 3ca2d3ca)
--12291--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.19.so ..
--12291--   .. CRC is valid
--12291-- Reading syms from /usr/lib/valgrind/memcheck-amd64-linux
--12291--   Considering /usr/lib/valgrind/memcheck-amd64-linux ..
--12291--   .. CRC mismatch (computed 4f1eed43 wanted a323a3ab)
--12291--    object doesn't have a symbol table
--12291--    object doesn't have a dynamic symbol table
--12291-- Scheduler: using generic scheduler lock implementation.
--12291-- Reading suppressions file: /usr/lib/valgrind/default.supp
==12291== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-    12291-by-fds-on-???
==12291== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-    12291-by-fds-on-???
==12291== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-    12291-by-fds-on-???
==12291== 
==12291== TO CONTROL THIS PROCESS USING vgdb (which you probably
==12291== don't want to do, unless you know exactly what you're doing,
==12291== or are doing some strange experiment):
==12291==   /usr/lib/valgrind/../../bin/vgdb --pid=12291 ...command...
==12291== 
==12291== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==12291==   /path/to/gdb ./ZmqProject
==12291== and then give GDB the following command
==12291==   target remote | /usr/lib/valgrind/../../bin/vgdb --pid=12291
==12291== --pid is optional if only one valgrind process is running
==12291== 
--12291-- REDIR: 0x4019c50 (ld-linux-x86-64.so.2:strlen) redirected to 0x380764b1 (???)
--12291-- Reading syms from /usr/lib/valgrind/vgpreload_core-amd64-    linux.so
--12291--   Considering /usr/lib/valgrind/vgpreload_core-amd64-linux.so ..
--12291--   .. CRC mismatch (computed fc68135e wanted 45f5e986)
--12291--    object doesn't have a symbol table
--12291-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
--12291--   Considering /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so ..
--12291--   .. CRC mismatch (computed ae683f7e wanted 08c06df2)
--12291--    object doesn't have a symbol table
==12291== WARNING: new redirection conflicts with existing -- ignoring it
--12291--     old: 0x04019c50 (strlen              ) R-> (0000.0) 0x380764b1 ???
--12291--     new: 0x04019c50 (strlen              ) R-> (2007.0) 0x04c2e1a0 strlen
--12291-- REDIR: 0x4019a00 (ld-linux-x86-64.so.2:index) redirected to 0x4c2dd50 (index)
--12291-- REDIR: 0x4019c20 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c2f2f0 (strcmp)
--12291-- REDIR: 0x401a970 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c31da0 (mempcpy)
--12291-- Reading syms from /usr/local/lib/libzmq.so.4.2.0
--12291-- Reading syms from /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
--12291--   Considering /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19 ..
--12291--   .. CRC mismatch (computed dc37bb90 wanted ea8c3b40)
--12291--    object doesn't have a symbol table
--12291-- Reading syms from /lib/x86_64-linux-gnu/libgcc_s.so.1
--12291--   Considering /lib/x86_64-linux-gnu/libgcc_s.so.1 ..
--12291--   .. CRC mismatch (computed 6116126e wanted 54e3f1f2)
--12291--    object doesn't have a symbol table
--12291-- Reading syms from /lib/x86_64-linux-gnu/libc-2.19.so
--12291--   Considering /lib/x86_64-linux-gnu/libc-2.19.so ..
--12291--   .. CRC mismatch (computed ac9b5ddb wanted a10d05bf)
--12291--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.19.so ..
--12291--   .. CRC is valid
--12291-- Reading syms from /lib/x86_64-linux-gnu/libpthread-2.19.so
--12291--   Considering /lib/x86_64-linux-gnu/libpthread-2.19.so ..
--12291--   .. CRC mismatch (computed 88040ace wanted 71b58165)
--12291--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/libpthread-2.19.so ..
--12291--   .. CRC is valid
--12291-- Reading syms from /lib/x86_64-linux-gnu/librt-2.19.so
--12291--   Considering /lib/x86_64-linux-gnu/librt-2.19.so ..
--12291--   .. CRC mismatch (computed 9efd3dd5 wanted ae0f290f)
--12291--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/librt-2.19.so ..
--12291--   .. CRC is valid
--12291-- Reading syms from /lib/x86_64-linux-gnu/libm-2.19.so
--12291--   Considering /lib/x86_64-linux-gnu/libm-2.19.so ..
--12291--   .. CRC mismatch (computed 08659659 wanted 7ce1b39a)
--12291--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/libm-2.19.so ..
--12291--   .. CRC is valid
--12291-- REDIR: 0x5696c50 (libc.so.6:strcasecmp) redirected to 0x4a25720 (_vgnU_ifunc_wrapper)
--12291-- REDIR: 0x5698f40 (libc.so.6:strncasecmp) redirected to 0x4a25720 (_vgnU_ifunc_wrapper)
--12291-- REDIR: 0x5696420 (libc.so.6:memcpy@GLIBC_2.2.5) redirected to 0x4a25720 (_vgnU_ifunc_wrapper)
--12291-- REDIR: 0x56946b0 (libc.so.6:rindex) redirected to 0x4c2da30 (rindex)
--12291-- REDIR: 0x56929b0 (libc.so.6:strlen) redirected to 0x4c2e0e0 (strlen)
--12291-- REDIR: 0x5695e90 (libc.so.6:__GI_memcmp) redirected to 0x4c30b80 (__GI_memcmp)
--12291-- REDIR: 0x5690f60 (libc.so.6:strcmp) redirected to 0x4a25720 (_vgnU_ifunc_wrapper)
--12291-- REDIR: 0x5749e00 (libc.so.6:__strcmp_ssse3) redirected to 0x4c2f1b0 (strcmp)
--12291-- REDIR: 0x514ee20 (libstdc++.so.6:operator new(unsigned long, std::nothrow_t const&)) redirected to 0x4c2b340 (operator new(unsigned long, std::nothrow_t const&))
--12291-- REDIR: 0x568c660 (libc.so.6:malloc) redirected to 0x4c2ab10 (malloc)
--12291-- REDIR: 0x568d130 (libc.so.6:calloc) redirected to 0x4c2cbf0 (calloc)
--12291-- REDIR: 0x514ed90 (libstdc++.so.6:operator new(unsigned long)) redirected to 0x4c2b070 (operator new(unsigned long))
--12291-- REDIR: 0x5759c90 (libc.so.6:__memmove_ssse3_back) redirected to 0x4c2f450 (memcpy@GLIBC_2.2.5)
--12291-- REDIR: 0x514d0f0 (libstdc++.so.6:operator delete(void*)) redirected to 0x4c2c250 (operator delete(void*))
--12291-- REDIR: 0x569b620 (libc.so.6:memcpy@@GLIBC_2.14) redirected to 0x4a25720 (_vgnU_ifunc_wrapper)
--12291-- REDIR: 0x56a1ec0 (libc.so.6:__memcpy_sse2_unaligned) redirected to 0x4c2f6b0 (memcpy@@GLIBC_2.14)
--12291-- REDIR: 0x5695e50 (libc.so.6:bcmp) redirected to 0x4a25720 (_vgnU_ifunc_wrapper)
--12291-- REDIR: 0x5769c60 (libc.so.6:__memcmp_sse4_1) redirected to 0x4c30c00 (__memcmp_sse4_1)
Connecting to hello world server…
--12291-- REDIR: 0x5690d40 (libc.so.6:__GI_strchr) redirected to 0x4c2db90 (__GI_strchr)
--12291-- REDIR: 0x5692e20 (libc.so.6:__GI_strncmp) redirected to 0x4c2e930 (__GI_strncmp)
--12291-- REDIR: 0x5695300 (libc.so.6:__GI_strstr) redirected to 0x4c32030 (__strstr_sse2)
--12291-- REDIR: 0x5695b00 (libc.so.6:memchr) redirected to 0x4c2f390 (memchr)
--12291-- REDIR: 0x569b670 (libc.so.6:__GI_memcpy) redirected to 0x4c2fc90 (__GI_memcpy)
--12291-- REDIR: 0x568cd00 (libc.so.6:free) redirected to 0x4c2bd80 (free)
--12291-- REDIR: 0x569d9b0 (libc.so.6:strchrnul) redirected to 0x4c319b0 (strchrnul)
--12291-- REDIR: 0x5748450 (libc.so.6:__strncasecmp_avx) redirected to 0x4c2eb60 (strncasecmp)
--12291-- REDIR: 0x5690fa0 (libc.so.6:__GI_strcmp) redirected to 0x4c2f200 (__GI_strcmp)
--12291-- REDIR: 0x5696ae0 (libc.so.6:__GI_stpcpy) redirected to 0x4c30da0 (__GI_stpcpy)
--12291-- Reading syms from /lib/x86_64-linux-gnu/libnss_files-2.19.so
--12291--   Considering /lib/x86_64-linux-gnu/libnss_files-2.19.so ..
--12291--   .. CRC mismatch (computed 69b3fb24 wanted 71fe8a31)
--12291--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/libnss_files-2.19.so ..
--12291--   .. CRC is valid
--12291-- REDIR: 0x5692430 (libc.so.6:__GI_strcpy) redirected to 0x4c2e2a0 (__GI_strcpy)
--12291-- REDIR: 0x569d7a0 (libc.so.6:rawmemchr) redirected to 0x4c319f0 (rawmemchr)
--12291-- REDIR: 0x5746de0 (libc.so.6:__strcasecmp_avx) redirected to 0x4c2ea80 (strcasecmp)
*** stack smashing detected ***: ./ZmqProject terminated
==12291== 
==12291== Process terminating with default action of signal 6 (SIGABRT)
==12291==    at 0x5640C37: raise (raise.c:56)
==12291==    by 0x5644027: abort (abort.c:89)
==12291==    by 0x567D2A3: __libc_message (libc_fatal.c:175)
==12291==    by 0x5714BBB: __fortify_fail (fortify_fail.c:38)
==12291==    by 0x5714B5F: __stack_chk_fail (stack_chk_fail.c:28)
==12291==    by 0x401D32: main (in /home/fds/Scrivania/ClientProgram/build/ZmqProject)
--12291-- Discarding syms at 0x74ff2a0-0x7504eb3 in /lib/x86_64-linux-gnu/libnss_files-2.19.so due to munmap()
==12291== 
==12291== HEAP SUMMARY:
==12291==     in use at exit: 0 bytes in 0 blocks
==12291==   total heap usage: 767 allocs, 767 frees, 176,711 bytes allocated
==12291== 
==12291== All heap blocks were freed -- no leaks are possible
==12291== 
==12291== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==12291== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Aborted (core dumped)

EDIT 2 - 今天我尝试使用 g++ 而不是 CMake 来编译我的 c++ 代码。

g++ -o client_cpp client_cpp.cpp -lzmq

现在 c++ 客户端 - python 服务器工作!

问题 2: 如何更改 CMakeLists.txt 以确保我的代码可以使用它?

我需要使用CMAKE

EDIT 3 如何将以下命令行“翻译”为 CMakeLists.txt

g++ -o client_cpp client_cpp.cpp -lzmq

最佳答案

Step 0:隔离甜蜜点

如上评论中所建议,请更新、运行发布 一个简单的自诊断代码修改的输出:

   int main ()
   {
      zmq::context_t context (1);
   // std::cout << "[1] .... + errno; // ----------------------------[1]

      zmq::socket_t socket (context, ZMQ_REQ);
   // std::cout << "[2] .... + errno; // ----------------------------[2]

      std::cout << "Connecting to hello world server…" << std::endl;
      socket.connect ("tcp://localhost:5555");
   // std::cout << "[3] .... + errno; // ----------------------------[3]

      std::string message = "hello";
      zmq::message_t request (message.size());
   // std::cout << "[4] .... + errno; // ----------------------------[4]

      memcpy (request.data (), (message.c_str()), (message.size()));
   // std::cout << "[5] .... + errno; // ----------------------------[5]

      socket.send (request);
   // std::cout << "[6] .... + errno; // ----------------------------[6]

      return 0;
   }

Step 1: re-read the ZeroMQ API details用于解释 errno

ZeroMQ团队为 API 文档付出了巨大的努力,您只能从阅读其中包含的完整详细信息和调试提示中受益。

您将在那里了解到,errno 通常与 rc 返回码相关联,以便当 API 服务调用遇到(非)标准情况时,增加状态中特定于上下文的状态解析策略。

示例: ...自早期发布以来,ØMQ 团队在这方面特别聪明和迂腐 - 荣誉

The zmq_send() function shall return number of bytes in the message if successful. Otherwise it shall return -1 and set errno to one of the values defined below.

Errors

EAGAIN Non-blocking mode was requested and the message cannot be sent at the moment.

ENOTSUP The zmq_send() operation is not supported by this socket type.

EFSM The zmq_send() operation cannot be performed on this socket at the moment due to the socket not being in the appropriate state. This error may occur with socket types that switch between several states, such as ZMQ_REP. See the messaging patterns section of zmq_socket(3) for more information.

ETERM The ØMQ context associated with the specified socket was terminated.

ENOTSOCK The provided socket was invalid.

EINTR The operation was interrupted by delivery of a signal before the message was sent.

EHOSTUNREACH The message cannot be routed.

/*                                                     Send a multi-part
                                                       message consisting
                                                       of three parts to socket */
rc = zmq_send ( socket, "ABC",   3, ZMQ_SNDMORE );     assert (rc == 3);
rc = zmq_send ( socket, "DEFGH", 5, ZMQ_SNDMORE );     assert (rc == 5);

/*                                                     Final part;
                                                       no more parts to follow */
rc = zmq_send ( socket, "JK",    2, 0 );               assert (rc == 2);

Step 2:查看失败调用的根本原因

没有来自 Step 0 的发布输出 没有机会继续学习为什么,所以请从这个开始,合理确定它会隔离确切位置 < strong>哪里 panic 状态起源。

这有助于所有人(包括此处)重新解释 Step 1 用于回答为什么

Always:适当注意资源释放和终止

分布式系统的架构并不像演示示例所示那样微不足道。一个统一的设计实践是你 - 程序设计者 - 对所有主要功能以及所有阻塞/ panic 状态负有端到端的责任,分布式系统或其任何较小的部分可以进入,包括最终释放在分布式系统中任何地方(动态)分配的每个资源。复杂的?当然。苛刻?当然。自律自律?总是。

这远远超出了 O/P 范围,但是虽然 python 对用户编程隐藏了许多资源管理职责,但其他语言绑定(bind)/包装器不需要如此慷慨。

总是准备,包括通过处理异常,ZeroMQ-套接字资源到.close()在非阻塞模式下(LINGER = 0)。

总是明确地,包括通过处理异常,.close()结束代码之前的 ZeroMQ 套接字。

始终明确地,包括通过处理异常,释放所有隐藏的 IO 线程工厂 .term() ZeroMQ Context 实例。

关于python - 为什么 "stack smashing detected"一旦 ZeroMQ C++ 客户端针对 python 服务器运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37614550/

相关文章:

c++ - 在WSL上安装Apache Kudu

python - 'ascii' 编解码器无法解码位置 5367 : ordinal not in range(128) 中的字节 0xe2

python - 允许保留关键字作为 Python 中的方法

C++ void* to int* - 获取 int* 指向的 int

C++——一个关于内存管理的问题

c++ - 在 cpp 文件中使用时推力静态断言

python - 如何在不打开新选项卡的情况下更改 Selenium 中的 URL (python)?

bash - 嵌入在 bash 中的 Python 不工作

C++ 指向数组的指针

c++ - 链接库 opencv cmake