如何捕捉在C ++ code奇怪的未定义行为? [英] How to catch strange undefined behaviour in C++ code?

查看:144
本文介绍了如何捕捉在C ++ code奇怪的未定义行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在服务器程序奇怪的行为。在简单的例子,它工作正常(我插入的痕迹无处不在,介子和ASIO)。

 的#include<介子/ HTTP / server.hpp>
#包括LT&;介子/ HTTP / response_writer.hpp>
#包括LT&;介子/ HTTP / response_reader.hpp>
#包括LT&;介子/ HTTP / request_writer.hpp>
#包括LT&;介子/ logger.hpp>
#包括LT&;介子/ sc​​heduler.hpp>诠释的main()
{
   介子:: single_service_scheduler脱落;
   shed.set_num_threads(1);
   提高:: shared_ptr的<介子:: HTTP ::服务器>服务器
   (新介子:: HTTP ::服务器(棚,5000));
   服务器 - > add_resource(/,handlerFunction);
   服务器 - >启动();
   睡眠(5);
}

输出是这样的。构建插座受体,建设插座端,TCP连接建立,一切工作正常。

 基本IO对象的构造
服务构造之后
基本IO对象的构造
服务构造之后
基本IO对象的构造
插座的地址是:0x9855fa4值:-1
服务构造之后
1422519945 INFO pion.http.server为HTTP资源添加请求处理:
1422519945 INFO pion.http.server启动服务器在端口5000
连接前创建
之前称为连接构造
基本IO对象的构造
basic_stream_socket ::结构
插座的地址是:0x9857514值:-1
impl.construct后
服务构造之后
基本IO对象的构造
服务构造之后
基本IO对象的构造
服务构造之后
SSL套接字构建
连接构造,is_ssl:0
连接后创建:0x98574f8
之前接受
后接受

在与同一code更复杂的方案,但与甲骨文和许多其他库的输出是这样的。

 基本IO对象的构造
服务构造之后
基本IO对象的构造
服务构造之后
基本IO对象的构造
插座的地址是:0xbfe47a64值:-1
服务构造之后
1422525476 INFO pion.http.server为HTTP资源添加请求处理:
连接前创建
基本IO对象的构造
服务构造之后
基本IO对象的构造
服务构造之后
连接后创建:0x8fe8b88
之前接受
在连接:: async_accept
后接受

没有第二个插槽创造,实际上,没有的呼叫连接::创建,但连接有地址,你可以看到。我有想法,一些地方对函数的地址写入连接::创建(或类似的东西)。你能帮帮我怎么能抓住这个?


解决方案

在Ubuntu中,我喜欢与的valgrind 运行(的 http://valgrind.org/ )。

 命令和apt-get安装的valgrind
Valgrind的./mypgrogram

它不报告所有的问题,但如果这样做,将报告的本质和起源。

同时建议:

 的valgrind --db-附加= YES ./myprogram

允许你调试(回溯,检查),并检测到违规/未初始化的内存引用时继续运行程序。


  

在一些老的Ubunti我不得不使用须藤,使的valgrind 能够连接 GDB

 须藤-E的valgrind --db-附加= YES ./myprogram


如果 TR1 / unordered_map 应该是相当琐碎与的std :: unordered_map

替换

例如。一个快速黑客

 的#include< unordered_map>空间std {空间TR1 {    使用std :: unordered_map;
    使用std ::散;
    //等等...
}}

当然,这是不好的做法,你可能只是想的std :: unordered_map 的std :: tr1 :: unordered_map之间的typedef 代替,但在快速检查的利益...

I have strange behaviour in server program. In simple example it works fine (I insert traces everywhere, in pion and asio).

#include <pion/http/server.hpp>
#include <pion/http/response_writer.hpp>
#include <pion/http/response_reader.hpp>
#include <pion/http/request_writer.hpp>
#include <pion/logger.hpp>
#include <pion/scheduler.hpp>

int main()
{
   pion::single_service_scheduler shed;
   shed.set_num_threads(1);
   boost::shared_ptr<pion::http::server> server
   (new pion::http::server(shed, 5000));
   server->add_resource("/", handlerFunction);
   server->start();
   sleep(5);
}

output is like this. Construct socket for acceptor, construct socket for client, tcp connection is created, all works fine.

basic io object constructor
after service construct
basic io object constructor
after service construct
basic io object constructor
Address of socket is: 0x9855fa4 value: -1
after service construct
1422519945 INFO pion.http.server Added request handler for HTTP resource: 
1422519945 INFO pion.http.server Starting server on port 5000
before connection create
before connection constructor called
basic io object constructor
basic_stream_socket::construct
Address of socket is: 0x9857514 value: -1
after impl.construct
after service construct
basic io object constructor
after service construct
basic io object constructor
after service construct
ssl socket constructed
connection constructor, is_ssl: 0
after connection create: 0x98574f8
before accept
after accept

In more complicated program with same code, but with oracle and many other libraries output is like this.

basic io object constructor
after service construct
basic io object constructor
after service construct
basic io object constructor
Address of socket is: 0xbfe47a64 value: -1
after service construct
1422525476 INFO pion.http.server Added request handler for HTTP resource: 
before connection create
basic io object constructor
after service construct
basic io object constructor
after service construct
after connection create: 0x8fe8b88
before accept
in connection::async_accept
after accept

No second socket created, actually, there is no call of connection::create, but connection has address as you can see. I have idea, that somewhere something writes on address of function connection::create (or something like). Can you please help, how can I catch this?

解决方案

On ubuntu, I like to run with valgrind (http://valgrind.org/).

sudo apt-get install valgrind
valgrind ./mypgrogram

It doesn't report all issues, but when it does, it will report the nature and origin.

Also recommended:

valgrind --db-attach=yes ./myprogram

Which allows you to debug (backtrace, inspect) and continue the program when a violation/uninitialized memory reference is detected.

On some older Ubunti I had to use sudo to make valgrind be able to attach gdb:

sudo -E valgrind --db-attach=yes ./myprogram

If tr1/unordered_map should be quite trivial to replace with std::unordered_map

E.g. with a quick hack

#include <unordered_map>

namespace std { namespace tr1 {

    using std::unordered_map;
    using std::hash;
    // etc...
} }

Of course this is not good practice, and you might just want to typedef between std::unordered_map and std::tr1::unordered_map instead, but in the interest of quick checks...

这篇关于如何捕捉在C ++ code奇怪的未定义行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆