cpprestsdk同时使用boost.asio,acceptor就一直报Invalid argument。
本文目录,首先总结问题,然后案例还原。
总结:
问题的根本在于boost.asio作为header-only库,运行程序与动态库之间容易因为版本错配而产生运行期莫名其妙的问题。
cpprestsdk使用boost-1.53编译了动态库,运行程序通过cmake找库boost-1.53,但同时cmake_module_path包含了boost-1.7x的cmake帮助模块,致使程序实际却使用了boost-1.7x包含目录的配置,boost-1.53的库目录配置。
由于boost.asio是header-only库,cpprestsdk.so按boost-1.53方式访问io_service,并编译进库;运行程序却按boost-1.7x方式访问io_service。
由于程序整体(包括cpprestsdk.so)使用到的boost.asio的函数接口,两个版本的boost.asio并没有不一致,所以编译没有发生问题。但是io_service的结构却不同,编译没有发生问题,却不会被人发现。因此在运行期间,程序按boost-1.7x的结构定义创建io_service,cpprestsdk却按boost-1.53的结构定义访问。如果是发生了SIGSEGV一类内存访问越界,还容易发现,但却没有触发,只是变量在内存布局位置不同,而问题转移到其它函数,这些函数因为依赖io_service的变量而因为访问不到正确的值,触发参数错误。
正是因为上述原因,cpprestsdk不能正确读出io_service的epoll_fd_,从而编译在cpprestsdk.so的部分boost.asio代码在操作epoll时失败,也就是将22号errno抛出异常std::invalid_argument。
案例:
不要去企图调试pplx。
场境,cpprestsdk中的pplx只是ppl的一个修剪版,功力只有几成,而且没有timer,timer是另一个名为Asynchronous Agents Lib的类。所以只能使用boost.asio提供的timer。但是一旦代码加入了boost.asio的timer,http_listen.open().wait()就永远地抛“open: Invalid argument”。本例的平台环境是 10cores centos7。
调试开始:

线程抛异常。
一共有42个线程。

由http_listener.open().wait()抛出异常的backtrace。
不要去调试pplx,企图单步进去分析。open()异步到thread_pool,wait()阻塞等待task<>结果,然后将错误抛出异常。
也不要去调试cpprestsdk,你会接受一系列task的洗礼,无功而返。
根据异常信息分析,类型是boost::system::system_error,也就是系统调用,open函数报参数错误?socket是用socket()而不是open()。
断socket()分析。


上两图,主线程,正在wait;线程41正执行open的任务操作。线程41是什么?

线程41是由boost.asio库的threadpool创建的线程,运行io_service::run()的。为什么有40个线程,每个core创建了4个线程。


最后出现了我们的关键字“listener"。

可惜的是,socket()并没有失败,成功创建了fd:6的socket。
然后一波跟踪后,发现eventpoll的文件描述符有问题。

fd: 1是我们熟知的stdout,故一定出错。是谁手欠去将 epoll_fd_改掉了。只好在下次启动时,断epoll_create,找到epoll_fd_地址进行监视。但是让人崩溃的是,监视这个epoll_fd_,程序却直奔抛异常。
在几乎断线索的情况下,反过来一想epoll_fd_为什么就没有被访问呢,也就是说,我断的epoll_fd_,不是执行代码看到epoll_fd_,原因只有一个可能,我俩眼里的 io_service西施压根不是同一时空的。一查CMakeFiles里的CXX_includes发现,我的程序原来在使用boost-1.7x,我编译的cpprestsdk在使用boost-1.53,尽管我强调了find_package(Boost 1.53 REQUIRED),无奈CMAKE_MODULE_PATH包含了boost-1.7的帮助cmake却不知道。
事实上,这个错误浪费了不止上面贴出的过程的时间。因为在开始没有头绪的时候,还要先排除boost::asio timer对cpprestsdk.so的影响,毕竟是加了它才出问题。还有痛苦的pplx异步任务跟踪,徒劳无功。上面的案例是归纳修正思路后,案例重演调试,也就是几步,因为我以经知道问题所在,方向还怎么走到清楚。实际上就一yuan大头,浪费了多少时间。
cpprestsdk同时使用boost.asio,acceptor就一直报Invalid argument。的更多相关文章
- boost asio acceptor 构造
boost::asio::io_service io_svc; boost::asio::ip::address_v4 lis_ip; // 默认监听本机所有IP boost::asio::ip::t ...
- BOOST.Asio——Tutorial
=================================版权声明================================= 版权声明:原创文章 谢绝转载 啥说的,鄙视那些无视版权随 ...
- Boost.Asio的使用技巧
基本概念 Asio proactor I/O服务 work类 run() vs poll() stop() post() vs dispatch() buffer类 缓冲区管理 I/O对象 socke ...
- (原创)如何使用boost.asio写一个简单的通信程序(一)
boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...
- 01--c实现基础客户端和服务端与c++ boost.asio实现对比
c实现服务端和客户端交互: 学习查阅的博客: https://blog.csdn.net/u011068702/article/details/54380259 https://blog.csdn.n ...
- c++ boost asio库初学习
前些日子研究了一个c++的一个socket库,留下范例代码给以后自己参考. 同步server: // asio_server.cpp : コンソール アプリケーションのエントリ ポイントを定義します. ...
- 如何在多线程leader-follower模式下正确的使用boost::asio。
#include <assert.h> #include <signal.h> #include <unistd.h> #include <iostream& ...
- BOOST.Asio——Overview
=================================版权声明================================= 版权声明:原创文章 谢绝转载 啥说的,鄙视那些无视版权随 ...
- boost asio sync
Service: #include<boost/asio.hpp> #include<boost/thread.hpp> #include<iostream> #i ...
随机推荐
- P3983 赛斯石(双背包)
这题不算难的,但是脑子真的特别乱.....传送门 \(Ⅰ.物品可以拆开来但船不能拆开来,所以1-10载重船的最大收益完全可以用背包求出来.\) \(Ⅱ.最后一定是选一些船走,而船的收益已经固定.所以用 ...
- B. Heaters 思维题 贪心 区间覆盖
B. Heaters 这个题目虽然只有1500的分数,但是我还是感觉挺思维的,我今天没有写出来,然后看了一下题解 很少做这种区间覆盖的题目,也不是很擅长,接下来讲讲我看完题解后的思路. 题目大意是:给 ...
- 循环结构(for、while)
3.4用for语句实现循环结构 什么是循环结构 for语句 1.什么是循环结构? 循环结构又称为重复结构,是利用计算机运算速度快以及能进行逻辑控制的特点来重复执行某些操作.重复执行的部分称为循环体. ...
- 三分钟快速搭建分布式高可用的Redis集群
这里的Redis集群指的是Redis Cluster,它是Redis在3.0版本正式推出的专用集群方案,有效地解决了Redis分布式方面的需求.当单机内存.并发.流量等遇到瓶颈的时候,可以采用这种Re ...
- [acdream_oj1732]求1到n的最小公倍数(n<=1e8)
题意:如标题 思路:如果n在10^6以内则可以用o(nlogn)的暴力,题目给定的是n<=1e8,暴力显然是不行的,考虑到1到n的最小公倍数可以写成2^p1*3^p2*5^p3*...这种素数的 ...
- Mysql 常用函数(19)- mod 函数
Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html mod 的作用 求余数,和%一样 mod的语法格式 ...
- 【雕爷学编程】MicroPython动手做(05)——零基础学MaixPy之LCD液晶屏
配套 2.4寸LCD屏 ST7789驱动器芯片(24P 320X240) ST7789驱动器芯片2.4寸LCD屏(24P 320X240)主要参数 1. 模块名称:液晶显示模块2. 型号:KD024C ...
- 【雕爷学编程】Arduino动手做(5)---热敏温度传感器模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备逐 ...
- React使用hook
Hook 是 React 16.8 的新增特性.它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性. 为什么会有hook 在组件之间复用状态逻辑很难,需要重新组织你 ...
- React:Element
React Elements 是构成React App的最小单位.React中的组件是由一个或多个Elements构成的. 和DOM不同,React Elements 是纯粹的JS对象.利用React ...