如何捕捉在C ++ code奇怪的未定义行为? [英] How to catch strange undefined behaviour in 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&;介子/ scheduler.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 functionconnection::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 makevalgrind
be able to attachgdb
:sudo -E valgrind --db-attach=yes ./myprogram
If
tr1/unordered_map
should be quite trivial to replace withstd::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
andstd::tr1::unordered_map
instead, but in the interest of quick checks...这篇关于如何捕捉在C ++ code奇怪的未定义行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!