本文目录,首先总结问题,然后案例还原。

总结:

问题的根本在于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。的更多相关文章

  1. boost asio acceptor 构造

    boost::asio::io_service io_svc; boost::asio::ip::address_v4 lis_ip; // 默认监听本机所有IP boost::asio::ip::t ...

  2. BOOST.Asio——Tutorial

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  啥说的,鄙视那些无视版权随 ...

  3. Boost.Asio的使用技巧

    基本概念 Asio proactor I/O服务 work类 run() vs poll() stop() post() vs dispatch() buffer类 缓冲区管理 I/O对象 socke ...

  4. (原创)如何使用boost.asio写一个简单的通信程序(一)

    boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...

  5. 01--c实现基础客户端和服务端与c++ boost.asio实现对比

    c实现服务端和客户端交互: 学习查阅的博客: https://blog.csdn.net/u011068702/article/details/54380259 https://blog.csdn.n ...

  6. c++ boost asio库初学习

    前些日子研究了一个c++的一个socket库,留下范例代码给以后自己参考. 同步server: // asio_server.cpp : コンソール アプリケーションのエントリ ポイントを定義します. ...

  7. 如何在多线程leader-follower模式下正确的使用boost::asio。

    #include <assert.h> #include <signal.h> #include <unistd.h> #include <iostream& ...

  8. BOOST.Asio——Overview

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  啥说的,鄙视那些无视版权随 ...

  9. boost asio sync

    Service: #include<boost/asio.hpp> #include<boost/thread.hpp> #include<iostream> #i ...

随机推荐

  1. Java——一文读懂Spring MVC执行流程

    说到Spring MVC执行流程,网上有很多这方面的文章介绍,但是都不太详细,作为一个初学者去读会有许多不理解的地方,今天这篇文章记录一下我学习Spring MVC的心得体会 话不多说,先上图: Sp ...

  2. M - Little Pony and Harmony Chest 状压dp

    M - Little Pony and Harmony Chest 怎么感觉自己越来越傻了,都知道状态的定义了还没有推出转移方程. 首先这个a的范围是0~30   这里可以推出 b数组的范围 0~60 ...

  3. 自定义比较器(IComparer接口的实现)

    class FileNameSort : IComparer { [System.Runtime.InteropServices.DllImport("Shlwapi.dll", ...

  4. STL下<algorithm>下的reverse函数

    定义: reverse用于C++中,对给定区间所有元素进行排序,是一种反向函数,不具备排序功能.sort函数包含在头文件为#include<algorithm>的C++标准库中. 语法: ...

  5. Spring Cloud 学习 之 Spring Cloud Eureka(概述)

    Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 前述: ​ 服务治理可以说是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务 ...

  6. 使用Proteus模拟操作HDG12864F-1液晶屏

    在Proteus中模拟了89C52操作HDG12864F-1液晶屏,原理图如下: 一.HDG12864F-1官网信息 该液晶屏是Hantronix的产品,官网上搜索出这个型号是系列型号中的一种,各种型 ...

  7. css3的 calc属性无效问题解决

    css3的 calc:计算属性. 运算符两边需要加空格,才有效. 错误示例:.mystyle{width:calc(100%-25px)}这样是不生效的 运算符"+ - * /"左 ...

  8. 谈谈R语言的缺点和优点

    编码不友好,对中文不友好,逼着你用RStudio.Jupyter Notebook/Jupyter Lab.图标丑,每次点击感觉辣眼睛. 为节省内存,R语言计算默认有效数字为7位,比Excel的15位 ...

  9. HDU 2017 (水)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2017 题目大意:给你段字符串,求出字符串中含有数字字符的个数 解题思路: 字符串输入输出的基本应用:h ...

  10. Hive环境搭建和SparkSql整合

    一.搭建准备环境 在搭建Hive和SparkSql进行整合之前,首先需要搭建完成HDFS和Spark相关环境 这里使用Hive和Spark进行整合的目的主要是: 1.使用Hive对SparkSql中产 ...