顯示文章

這裡允許您檢視這個會員的所有文章。請注意, 您只能看見您有權限閱讀的文章。


文章 - FIEND

頁: 1 [2] 3 4 ... 24
31

經過我瘋狂的 DOS .... JSONCPP 果然 不會掛了...

又學了一招 這次比較快 , 馬上就有善心人事 SKYPE 密我 答案了 @@.  ~XD..



32

呼~這問題比較多人遇到 XD ....

自己一直在~TRACE 半天 CODE 剛才馬上有人貼網址給我~>_<"

http://blog.eaxi.com/jsoncpp%E6%89%A7%E8%A1%8C%E6%97%B6%E9%94%99%E8%AF%AF%EF%BC%9A-json-test-src-lib-json-json-value/

soncpp執行時錯誤:
json_test: src/lib_json/json_value.cpp:1025: Json::Value& Json::Value::resolveReference(const char*, bool): Assertion `type_ == nullValue || type_ == objectValue』 failed.

原因分析:
Jsoncpp解析非法json時,會自動容錯成字符類型。對字符類型取下標時,會觸發assert終止進程。

解決方法:
方案1 對Json::Value取下標前,先判斷(value.type()==Json::objectValue)。
方案2 啟用嚴格模式,讓非法的json解析時直接返回false,不自動容錯。
Json::Features f = Json::Features::strictMode();
Json::Reader reader(f);

33
沒意外是 jsoncpp 底下的
src/lib_json/json_value.cpp:1025:
Json::Value& Json::Value::resolveReference(const char*, bool): Assertion `type_ == nullValue || type_ == objectValue' failed.

造成的.

又要開始痛苦的找問題了 @@"



34
看起來 jsoncpp 的穩定性也沒很好.

送了 100000000 組 搞了 幾十個併發攻擊 請求後 , 直接把它給弄死了.....

繼續研究~~


[root@FIEND wge_server]# gdb sbin/wge core.30747
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-56.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/cpp/wge_server/sbin/wge...done.
[New Thread 30749]
[New Thread 30750]
[New Thread 30748]
[New Thread 30747]
Missing separate debuginfo for /usr/local/wge/server/boost/lib/libboost_system.so.1.51.0
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/43/e38b856af532331942a23fd0cfd05c3a7eb6b2
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libPhpFpm.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/7b/cb561cb29f74b1fd8f6121b1ef8b24babe5890
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libWgeBase64.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/1b/1cd9c7370849727662953e57da8d4e5c0e7c78
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libWgeJsoncpp.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/b8/1f4d99f40ef14d4dbb56900669dad627d4f09d
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libZlib.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/6f/50ef6e38d3cb1e25ba8b37d6bce700e6ee6d0f
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libWgeOpenssl.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/a1/6668595410ed1f78e46ce2b00168c58107f102
Missing separate debuginfo for /usr/local/wge/server/poco/lib/libPocoFoundation.so.12
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/9b/d1532f5e378a14a2cd3d2ba460fd79ebae579b
Missing separate debuginfo for
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/74/22987f6cfa699f465b0327139aac3fdac4a838
Reading symbols from /usr/local/wge/server/boost/lib/libboost_system.so.1.51.0...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/boost/lib/libboost_system.so.1.51.0
Reading symbols from /usr/local/wge/server/wge/lib/libPhpFpm.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libPhpFpm.so
Reading symbols from /usr/local/wge/server/wge/lib/libWgeBase64.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libWgeBase64.so
Reading symbols from /usr/local/wge/server/wge/lib/libWgeJsoncpp.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libWgeJsoncpp.so
Reading symbols from /usr/local/wge/server/wge/lib/libZlib.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libZlib.so
Reading symbols from /usr/local/wge/server/wge/lib/libWgeOpenssl.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libWgeOpenssl.so
Reading symbols from /usr/lib64/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /lib64/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/librt.so.1
Reading symbols from /usr/local/wge/server/poco/lib/libPocoFoundation.so.12...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/poco/lib/libPocoFoundation.so.12
Reading symbols from /usr/lib64/libcrypto.so.10...(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/libcrypto.so.10
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /lib64/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/libdl.so.2
Reading symbols from /lib64/libz.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libz.so.1
Core was generated by `./sbin/wge'.
Program terminated with signal 6, Aborted.
#0  0x000000342b6328a5 in raise () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.el6_3.3.x86_64 libgcc-4.4.6-4.el6.x86_64 libstdc++-4.4.6-4.el6.x86_64 openssl-1.0.0-25.el6_3.1.x86_64 zlib-1.2.3-27.el6.x86_64
(gdb) bt
#0  0x000000342b6328a5 in raise () from /lib64/libc.so.6
#1  0x000000342b634085 in abort () from /lib64/libc.so.6
#2  0x000000342b62ba1e in __assert_fail_base () from /lib64/libc.so.6
#3  0x000000342b62bae0 in __assert_fail () from /lib64/libc.so.6
#4  0x00002abae62a2e16 in Json::Value::resolveReference(char const*, bool) () from /usr/local/wge/server/wge/lib/libWgeJsoncpp.so
#5  0x00002abae6298217 in wgeJsoncpp::wgeJsoncpp::getUID() () from /usr/local/wge/server/wge/lib/libWgeJsoncpp.so
#6  0x0000000000416d47 in session::readClientRequest (this=0x2abaec008790) at ./src/wge.cpp:613
#7  0x000000000041701d in session::handle_read (this=0x2abaec008790, error=<value optimized out>, bytes_transferred=<value optimized out>) at ./src/wge.cpp:655
#8  0x0000000000409065 in call<boost::shared_ptr<session>, boost::system::error_code const, unsigned long> (owner=<value optimized out>, base=<value optimized out>)
    at /usr/local/wge/server/boost/include/boost/bind/mem_fn_template.hpp:271
#9  operator()<boost::shared_ptr<session> > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/mem_fn_template.hpp:286
#10 operator()<boost::_mfi::mf2<void, session, const boost::system::error_code&, long unsigned int>, boost::_bi::list2<const boost::system::error_code&, const long unsigned int&> > (owner=<value optimized out>,
    base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/bind.hpp:392
#11 operator()<boost::system::error_code, long unsigned int> (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/bind_template.hpp:102
#12 operator() (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/bind_handler.hpp:118
#13 asio_handler_invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, boost::system::error_code, unsigned long> > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/handler_invoke_hook.hpp:64
#14 invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, boost::system::error_code, unsigned long>, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/handler_invoke_helpers.hpp:39
#15 boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >::do_complete (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/reactive_socket_recv_op.hpp:110
#16 0x0000000000411c75 in complete (this=0x2abaec000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/task_io_service_operation.hpp:37
#17 do_run_one (this=0x2abaec000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/task_io_service.ipp:419
#18 boost::asio::detail::task_io_service::run (this=0x2abaec000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/task_io_service.ipp:160
#19 0x0000000000404d2e in run () at /usr/local/wge/server/boost/include/boost/asio/impl/io_service.ipp:59
#20 startServer () at ./src/wge.cpp:888
#21 0x0000003e978b6470 in ?? () from /usr/lib64/libstdc++.so.6
#22 0x000000342be07851 in start_thread () from /lib64/libpthread.so.0
#23 0x000000342b6e76dd in clone () from /lib64/libc.so.6
(gdb) up
#1  0x000000342b634085 in abort () from /lib64/libc.so.6
(gdb)
#2  0x000000342b62ba1e in __assert_fail_base () from /lib64/libc.so.6
(gdb)
#3  0x000000342b62bae0 in __assert_fail () from /lib64/libc.so.6
(gdb)
#4  0x00002abae62a2e16 in Json::Value::resolveReference(char const*, bool) () from /usr/local/wge/server/wge/lib/libWgeJsoncpp.so
(gdb)
#5  0x00002abae6298217 in wgeJsoncpp::wgeJsoncpp::getUID() () from /usr/local/wge/server/wge/lib/libWgeJsoncpp.so
(gdb)
#6  0x0000000000416d47 in session::readClientRequest (this=0x2abaec008790) at ./src/wge.cpp:613
613                                     uid = wgejson.getUID() ;
(gdb)
#7  0x000000000041701d in session::handle_read (this=0x2abaec008790, error=<value optimized out>, bytes_transferred=<value optimized out>) at ./src/wge.cpp:655
655                            readClientRequest() ; // call readClientRequest()  , and use async_write
(gdb)
#8  0x0000000000409065 in call<boost::shared_ptr<session>, boost::system::error_code const, unsigned long> (owner=<value optimized out>, base=<value optimized out>)
    at /usr/local/wge/server/boost/include/boost/bind/mem_fn_template.hpp:271
271             BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2);
(gdb)
#9  operator()<boost::shared_ptr<session> > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/mem_fn_template.hpp:286
286             BOOST_MEM_FN_RETURN call(u, p, a1, a2);
(gdb)
#10 operator()<boost::_mfi::mf2<void, session, const boost::system::error_code&, long unsigned int>, boost::_bi::list2<const boost::system::error_code&, const long unsigned int&> > (owner=<value optimized out>,
    base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/bind.hpp:392
392             unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]);
(gdb)
#11 operator()<boost::system::error_code, long unsigned int> (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/bind_template.hpp:102
102             BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
(gdb)
#12 operator() (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/bind_handler.hpp:118
118         handler_(static_cast<const Arg1&>(arg1_),
(gdb)
#13 asio_handler_invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, boost::system::error_code, unsigned long> > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/handler_invoke_hook.hpp:64
64        function();
(gdb)
#14 invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, boost::system::error_code, unsigned long>, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/handler_invoke_helpers.hpp:39
39        asio_handler_invoke(function, boost::addressof(context));
(gdb)
#15 boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >::do_complete (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/reactive_socket_recv_op.hpp:110
110           boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
(gdb)
#16 0x0000000000411c75 in complete (this=0x2abaec000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/task_io_service_operation.hpp:37
37          func_(&owner, this, ec, bytes_transferred);
(gdb)
#17 do_run_one (this=0x2abaec000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/task_io_service.ipp:419
419             o->complete(*this, ec, task_result);
(gdb)
#18 boost::asio::detail::task_io_service::run (this=0x2abaec000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/task_io_service.ipp:160
160       for (; do_run_one(lock, this_thread, ec); lock.lock())
(gdb)
#19 0x0000000000404d2e in run () at /usr/local/wge/server/boost/include/boost/asio/impl/io_service.ipp:59
59        std::size_t s = impl_.run(ec);
(gdb)
#20 startServer () at ./src/wge.cpp:888
888                     io_service.run();
(gdb)
#21 0x0000003e978b6470 in ?? () from /usr/lib64/libstdc++.so.6
(gdb)
#22 0x000000342be07851 in start_thread () from /lib64/libpthread.so.0
(gdb)
#23 0x000000342b6e76dd in clone () from /lib64/libc.so.6
(gdb)
Initial frame selected; you cannot go up.

35
玩了好久~~~還沒死~~

現在正用 SERVER DOS~CLIENT 端 :

這次真的搞定了~嘿嘿..



DOS 攻擊~伺服端  :

弄好久了~~還沒死~~......


36
搞定 ................




        bool addUsock(int uid,tcp::socket* psocket){
                socketRet = usock.insert(pair<int,tcp::socket*>(uid,psocket)); ;
                if(socketRet.second == false){
                        return false ;
                }
                return true ;
        }


        tcp::socket* getUsock(int uid){

                if(usock.count(uid) > 0 ){
                        psocket = usock.find(uid)->second;
                }
                return psocket ;
        }

        void usockClose(int uid){
                psocket = NULL ;
                if(uid > 0 ){
                        psocket = getUsock(uid) ;
                        if(DEBUG_MODE == 1){
                                std::cout << "psock          : " << psocket << std::endl ;
                                std::cout << "psock stat     : " << psocket->is_open() << std::endl ;
                                std::cout << "option         : " << psocket->get_option(option, ec) << std::endl ;
                                std::cout << "error code     : " << ec.value() << std::endl ;
                        }
                        if(psocket != NULL){
                                psocket->get_option(option, ec) ;
                                if(ec.value() == 0 ){
                                        //psocket->shutdown(boost::asio::ip::tcp::socket::shutdown_both,ec);
                                        psocket->close(ec);
                                }
                        }
                }
        }



        std::map<int,tcp::socket*> usock;
        std::map<int,tcp::socket*>::iterator usockit;
        std::pair<map<int,tcp::socket*>::iterator,bool> socketRet ;
        tcp::socket* psocket ;
        boost::system::error_code ec;
        boost::asio::ip::tcp::socket::keep_alive option;
 

37
#1  close (this=0x2ab8fc002e10) at /usr/local/wge/server/boost/include/boost/asio/stream_socket_service.hpp:151
151         return service_impl_.close(impl, ec);
(gdb)
#2  boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::close (this=0x2ab8fc002e10) at /usr/local/wge/server/boost/include/boost/asio/basic_socket.hpp:309
309         this->get_service().close(this->get_implementation(), ec);


解決了...

我是硬解的 目前還不知道為什麼指標丟到 close  內 .

impl 為什麼會 Segmentation fault.

於是我 把 指標 socket 的狀態一個個倒出來看.


        std::map<int,tcp::socket*> usock;
        std::map<int,tcp::socket*>::iterator usockit;
        std::pair<map<int,tcp::socket*>::iterator,bool> socketRet ;
        tcp::socket* psocket ;

        boost::system::error_code ec;
        boost::asio::ip::tcp::socket::keep_alive option;

        psocket = getUsock(uid) ;
        psocket->get_option(option, ec)  ;   <<< 這裡每次在還沒有出現 Segmentation fault. 時會倒出 0
                                                                         但是一但出錯就會倒出 9 , 88
                                                                         於是我把 倒出來是 9 , 88 以外的動作停下來 讓 0 的動作發生.
                                                                         有空再查 system:9 , system:88 是什麼意思.



這個問題有可能是重覆 FREE 記憶體造成的.

等我找到 system:9 代表什麼意思就有解答了.

38
XD 一定要休息了....

有可能是我自己在異步IO下長指標造成的錯亂.

晚一點利用 BOOST 內建的智慧型指標 shared_ptr 再來玩一次看看.

使用 智慧型指標也一樣 ....

重新 TRACE  :

Program terminated with signal 11, Segmentation fault.
#0  0x000000000040d19b in close (this=0x2ab8fc002e10) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/reactive_socket_service_base.ipp:103
103             (impl.state_ & socket_ops::possible_dup) == 0);
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.el6_3.3.x86_64 libgcc-4.4.6-4.el6.x86_64 libstdc++-4.4.6-4.el6.x86_64 openssl-1.0.0-25.el6_3.1.x86_64 zlib-1.2.3-27.el6.x86_64
(gdb) bt
#0  0x000000000040d19b in close (this=0x2ab8fc002e10) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/reactive_socket_service_base.ipp:103
#1  close (this=0x2ab8fc002e10) at /usr/local/wge/server/boost/include/boost/asio/stream_socket_service.hpp:151
#2  boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::close (this=0x2ab8fc002e10) at /usr/local/wge/server/boost/include/boost/asio/basic_socket.hpp:309
#3  0x00000000004148f3 in session::loginChk (this=0x2ab8fc006650) at ./src/wge.cpp:446
#4  0x0000000000415020 in session::readClientRequest (this=0x2ab8fc006650) at ./src/wge.cpp:608
#5  0x0000000000409455 in call<boost::shared_ptr<session>, boost::system::error_code const, unsigned long> (owner=<value optimized out>, base=<value optimized out>)
    at /usr/local/wge/server/boost/include/boost/bind/mem_fn_template.hpp:271
#6  operator()<boost::shared_ptr<session> > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/mem_fn_template.hpp:286
#7  operator()<boost::_mfi::mf2<void, session, const boost::system::error_code&, long unsigned int>, boost::_bi::list2<const boost::system::error_code&, const long unsigned int&> > (owner=<value optimized out>,
    base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/bind.hpp:392
#8  operator()<boost::system::error_code, long unsigned int> (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/bind_template.hpp:102
#9  operator() (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/bind_handler.hpp:118
#10 asio_handler_invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, boost::system::error_code, unsigned long> > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/handler_invoke_hook.hpp:64
#11 invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, boost::system::error_code, unsigned long>, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/handler_invoke_helpers.hpp:39
#12 boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >::do_complete (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/reactive_socket_recv_op.hpp:110
#13 0x000000000040b752 in complete (owner=0x2ab8fc000910, base=<value optimized out>, ec=..., bytes_transferred=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/task_io_service_operation.hpp:37
#14 boost::asio::detail::epoll_reactor::descriptor_state::do_complete (owner=0x2ab8fc000910, base=<value optimized out>, ec=..., bytes_transferred=<value optimized out>)
    at /usr/local/wge/server/boost/include/boost/asio/detail/impl/epoll_reactor.ipp:650
#15 0x000000000040e885 in complete (this=0x2ab8fc000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/task_io_service_operation.hpp:37
#16 do_run_one (this=0x2ab8fc000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/task_io_service.ipp:419
#17 boost::asio::detail::task_io_service::run (this=0x2ab8fc000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/task_io_service.ipp:160
#18 0x000000000040484e in run () at /usr/local/wge/server/boost/include/boost/asio/impl/io_service.ipp:59
#19 startServer () at ./src/wge.cpp:873
#20 0x0000003e978b6470 in ?? () from /usr/lib64/libstdc++.so.6
#21 0x000000342be07851 in start_thread () from /lib64/libpthread.so.0
#22 0x000000342b6e76dd in clone () from /lib64/libc.so.6
(gdb) up
#1  close (this=0x2ab8fc002e10) at /usr/local/wge/server/boost/include/boost/asio/stream_socket_service.hpp:151
151         return service_impl_.close(impl, ec);
(gdb)
#2  boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::close (this=0x2ab8fc002e10) at /usr/local/wge/server/boost/include/boost/asio/basic_socket.hpp:309
309         this->get_service().close(this->get_implementation(), ec);
(gdb)
#3  0x00000000004148f3 in session::loginChk (this=0x2ab8fc006650) at ./src/wge.cpp:446
446                                                     userPtr->getUsock(uid)->close();
(gdb)
#4  0x0000000000415020 in session::readClientRequest (this=0x2ab8fc006650) at ./src/wge.cpp:608
608                                             loginChk();
(gdb)
#5  0x0000000000409455 in call<boost::shared_ptr<session>, boost::system::error_code const, unsigned long> (owner=<value optimized out>, base=<value optimized out>)
    at /usr/local/wge/server/boost/include/boost/bind/mem_fn_template.hpp:271
271             BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2);
(gdb)
#6  operator()<boost::shared_ptr<session> > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/mem_fn_template.hpp:286
286             BOOST_MEM_FN_RETURN call(u, p, a1, a2);
(gdb)
#7  operator()<boost::_mfi::mf2<void, session, const boost::system::error_code&, long unsigned int>, boost::_bi::list2<const boost::system::error_code&, const long unsigned int&> > (owner=<value optimized out>,
    base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/bind.hpp:392
392             unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]);
(gdb)
#8  operator()<boost::system::error_code, long unsigned int> (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/bind_template.hpp:102
102             BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
(gdb)
#9  operator() (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/bind_handler.hpp:118
118         handler_(static_cast<const Arg1&>(arg1_),
(gdb)
#10 asio_handler_invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, boost::system::error_code, unsigned long> > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/handler_invoke_hook.hpp:64
64        function();
(gdb)
#11 invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, boost::system::error_code, unsigned long>, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/handler_invoke_helpers.hpp:39
39        asio_handler_invoke(function, boost::addressof(context));
(gdb)
#12 boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >::do_complete (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/reactive_socket_recv_op.hpp:110
110           boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
(gdb)
#13 0x000000000040b752 in complete (owner=0x2ab8fc000910, base=<value optimized out>, ec=..., bytes_transferred=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/task_io_service_operation.hpp:37
37          func_(&owner, this, ec, bytes_transferred);
(gdb)
#14 boost::asio::detail::epoll_reactor::descriptor_state::do_complete (owner=0x2ab8fc000910, base=<value optimized out>, ec=..., bytes_transferred=<value optimized out>)
    at /usr/local/wge/server/boost/include/boost/asio/detail/impl/epoll_reactor.ipp:650
650           op->complete(*owner, ec, 0);
(gdb)
#15 0x000000000040e885 in complete (this=0x2ab8fc000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/task_io_service_operation.hpp:37
37          func_(&owner, this, ec, bytes_transferred);
(gdb)
#16 do_run_one (this=0x2ab8fc000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/task_io_service.ipp:419
419             o->complete(*this, ec, task_result);
(gdb)
#17 boost::asio::detail::task_io_service::run (this=0x2ab8fc000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/task_io_service.ipp:160
160       for (; do_run_one(lock, this_thread, ec); lock.lock())
(gdb)
#18 0x000000000040484e in run () at /usr/local/wge/server/boost/include/boost/asio/impl/io_service.ipp:59
59        std::size_t s = impl_.run(ec);
(gdb)
#19 startServer () at ./src/wge.cpp:873
873                     io_service.run();
(gdb)

39
課後溫習+認證考試 / Re: RHCSA PASS
« 於: 2012-09-06 10:30 »
大大受教了.....
小弟屬於懶惰型的,知道自己看書學LINUX絕對只有三分鐘熱度,所以去參加RHCE認證班,讓自己有動力去學(錢都花下去了.... :P
雖然已考到了RHCE,不過小弟每天還是會花至少2小時去玩linux,不管玩什麼都好,就像online game一樣,有上線就有經驗嘛! ;D
現在就好像中毒一樣,下班回到家不碰碰linux還真的不蘇湖,最近小弟在學LDAP,遇到一些問題睡覺還會睡不好,一直在想著要怎麼解決...... :P

呵呵~開始中毒了.

我是超級懶惰型 , 超級不愛看書和補習 .

以前公司安排的教育訓練 和請人回來教 我都沒有參與.

所以我身上一張證照都沒有 , 因為我討厭去補習班和研討會浪費時間.

我的信念一直都是 實作 才是學習技術的王道.

通常我都是把環境建起來 , 如果遇到問題才會去買書回來參考.

結果不小心 , 我這十多年來也買了 二千多本電腦書 , 光 LINUX 我就有 幾十本.

天瓏的老闆看到我都直接給我折扣 , 不用看天瓏卡 @@"

上個月我才剛去天瓏一口氣買了七千多塊 XD.

不是我愛看書 , 而是我遇到問題時 , 才會想要去書上找問題.

我覺得沒有在實作是無法跟作者共嗚的.

也無法吸收作者的原意.

書只不過是遇到問題時 可以給你對的方向和觀念的工具.

多實作 才可以學到東西.



40
課後溫習+認證考試 / Re: RHCSA PASS
« 於: 2012-09-06 08:45 »
這是我個人的看法~~

學習 LINUX 的方式 , 考試 認證教材 只是一種輔助 跟 學習的管道.

不代表你考過了就真的有 解決問題的能力.

老實說 我在請新人時 , 會注意一個年資超過三年的人是不是證照太多.

如果太多我可能完全不會想用他.

因為我會懷疑 一個 進入職場三年的人 怎麼還有那麼多時間去考證照.

真的有能力 應該都在忙工作才對 , 沒什麼時間考證照.



我從 READ HEAD 6.1 玩到 FEDORA 18

從 READ HEAD 7.1 一直到  FEDORA 12  我的電腦一直都是 用它們當作業系統.

花大把的時間 去看書 , 背內容.

不如直接把你家的 錢軟作業系統砍了 , 很扎實的把 自己的作業系統換成 LINUX .

要什麼 APP 都自己 COMPILER .

不要太依懶 RPM .

這種方式雖然一開始很辛苦 , 你可能前面幾年會為了它都睡不好.

不過觀念和解決問題的能力才會加強.

慢慢的對你來說~LINUX 的問題 可能慢慢會變的 比吃飯走路還平常.

就好像學武功一樣 , 不停的聽老師講招術 , 不停的看書學招術 .

還不如一個天天找人 PK 的人有戰鬥力.

職場要的是會打架的人 不是書呆子.

不停的替自己創造 實作機會的人反而更能解決問題.


我在公司對一個年資不滿三年的人的要求是把錢軟砍了 換成 LINUX 作為開發用的主要作業系統.

證照只是一個新人剛開始進入職場的能力參考或加分效果.

真的進入職場 , 一個技術人員 最大的價值 不是證照多少.

而是 解決問題的能力和速度 .

而我在找資深人員時 決定這個人的薪水 高低 , 參考指標己經不是證照了.

而是他 做過那些大型系統 , 解決過那些很難的問題.

他才可以在團隊裡幫上很大的忙.

除非未來你想要教課 , 服務社會 , 不然其實比較建議 適可而止 .




41
shared_ptr.hpp , Version 1.51

#ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
#define BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED

//
//  shared_ptr.hpp
//
//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
//  Copyright (c) 2001-2008 Peter Dimov
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
//  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
//

#include <boost/config.hpp>   // for broken compiler workarounds

#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
#include <boost/smart_ptr/detail/shared_ptr_nmt.hpp>
#else

// In order to avoid circular dependencies with Boost.TR1
// we make sure that our include of <memory> doesn't try to
// pull in the TR1 headers: that's why we use this header
// rather than including <memory> directly:
#include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr

#include <boost/assert.hpp>
#include <boost/checked_delete.hpp>
#include <boost/throw_exception.hpp>
#include <boost/smart_ptr/detail/shared_count.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/smart_ptr/detail/sp_convertible.hpp>

#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
#include <boost/smart_ptr/detail/spinlock_pool.hpp>
#include <boost/memory_order.hpp>
#endif

#include <algorithm>            // for std::swap
#include <functional>           // for std::less
#include <typeinfo>             // for std::bad_cast
#include <cstddef>              // for std::size_t

#if !defined(BOOST_NO_IOSTREAM)
#if !defined(BOOST_NO_IOSFWD)
#include <iosfwd>               // for std::basic_ostream
#else
#include <ostream>
#endif
#endif


namespace boost
{

template<class T> class shared_ptr;
template<class T> class weak_ptr;
template<class T> class enable_shared_from_this;
template<class T> class enable_shared_from_this2;

namespace detail
{

struct static_cast_tag {};
struct const_cast_tag {};
struct dynamic_cast_tag {};
struct polymorphic_cast_tag {};

template<class T> struct shared_ptr_traits
{
    typedef T & reference;
};

template<> struct shared_ptr_traits<void>
{
    typedef void reference;
};

#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)

template<> struct shared_ptr_traits<void const>
{
    typedef void reference;
};

template<> struct shared_ptr_traits<void volatile>
{
    typedef void reference;
};

template<> struct shared_ptr_traits<void const volatile>
{
    typedef void reference;
};

#endif
// enable_shared_from_this support

template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
{
    if( pe != 0 )
    {
        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
    }
}

template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe )
{
    if( pe != 0 )
    {
        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
    }
}

#ifdef _MANAGED

// Avoid C4793, ... causes native code generation

struct sp_any_pointer
{
    template<class T> sp_any_pointer( T* ) {}
};

inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer )
{
}

#else // _MANAGED

inline void sp_enable_shared_from_this( ... )
{
}

#endif // _MANAGED

#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )

// rvalue auto_ptr support based on a technique by Dave Abrahams

template< class T, class R > struct sp_enable_if_auto_ptr
{
};

template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
{
    typedef R type;
};

#endif

} // namespace detail

//
//  shared_ptr
//
//  An enhanced relative of scoped_ptr with reference counted copy semantics.
//  The object pointed to is deleted when the last shared_ptr pointing to it
//  is destroyed or reset.
//

template<class T> class shared_ptr
{
private:

    // Borland 5.5.1 specific workaround
    typedef shared_ptr<T> this_type;

public:

    typedef T element_type;
    typedef T value_type;
    typedef T * pointer;
    typedef typename boost::detail::shared_ptr_traits<T>::reference reference;

    shared_ptr(): px(0), pn() // never throws in 1.30+
    {
    }

    template<class Y>
    explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
    {
        boost::detail::sp_enable_shared_from_this( this, p, p );
    }

    //
    // Requirements: D's copy constructor must not throw
    //
    // shared_ptr will release p by calling d(p)
    //

    template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
    {
        boost::detail::sp_enable_shared_from_this( this, p, p );
    }

    // As above, but with allocator. A's copy constructor shall not throw.

    template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
    {
        boost::detail::sp_enable_shared_from_this( this, p, p );
    }

//  generated copy constructor, destructor are fine...

#if defined( BOOST_HAS_RVALUE_REFS )

// ... except in C++0x, move disables the implicit copy

    shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
    {
    }

#endif

    template<class Y>
    explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw
    {
        // it is now safe to copy r.px, as pn(r.pn) did not throw
        px = r.px;
    }

    template<class Y>
    shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws
    {
        if( !pn.empty() )
        {
            px = r.px;
        }
    }

    template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )

    shared_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )

#else

    shared_ptr( shared_ptr<Y> const & r )

#endif
    : px( r.px ), pn( r.pn ) // never throws
    {
    }

    // aliasing
    template< class Y >
    shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
    {
    }

    template<class Y>
    shared_ptr(shared_ptr<Y> const & r, boost::detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
    {
    }

    template<class Y>
    shared_ptr(shared_ptr<Y> const & r, boost::detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn)
    {
    }

    template<class Y>
    shared_ptr(shared_ptr<Y> const & r, boost::detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
    {
        if(px == 0) // need to allocate new counter -- the cast failed
        {
            pn = boost::detail::shared_count();
        }
    }
    template<class Y>
    shared_ptr(shared_ptr<Y> const & r, boost::detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
    {
        if(px == 0)
        {
            boost::throw_exception(std::bad_cast());
        }
    }

#ifndef BOOST_NO_AUTO_PTR

    template<class Y>
    explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn()
    {
        Y * tmp = r.get();
        pn = boost::detail::shared_count(r);
        boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
    }

#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )

    template<class Ap>
    explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
    {
        typename Ap::element_type * tmp = r.get();
        pn = boost::detail::shared_count( r );
        boost::detail::sp_enable_shared_from_this( this, tmp, tmp );
    }


#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

#endif // BOOST_NO_AUTO_PTR

    // assignment

    shared_ptr & operator=( shared_ptr const & r ) // never throws
    {
        this_type(r).swap(*this);
        return *this;
    }

#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)

    template<class Y>
    shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
    {
        this_type(r).swap(*this);
        return *this;
    }

#endif

#ifndef BOOST_NO_AUTO_PTR

    template<class Y>
    shared_ptr & operator=( std::auto_ptr<Y> & r )
    {
        this_type(r).swap(*this);
        return *this;
    }
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )

    template<class Ap>
    typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
    {
        this_type( r ).swap( *this );
        return *this;
    }


#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION

#endif // BOOST_NO_AUTO_PTR

// Move support

#if defined( BOOST_HAS_RVALUE_REFS )

    shared_ptr( shared_ptr && r ): px( r.px ), pn() // never throws
    {
        pn.swap( r.pn );
        r.px = 0;
    }

    template<class Y>
#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )

    shared_ptr( shared_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )

#else

    shared_ptr( shared_ptr<Y> && r )

#endif
    : px( r.px ), pn() // never throws
    {
        pn.swap( r.pn );
        r.px = 0;
    }

    shared_ptr & operator=( shared_ptr && r ) // never throws
    {
        this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
        return *this;
    }

    template<class Y>
    shared_ptr & operator=( shared_ptr<Y> && r ) // never throws
    {
        this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
        return *this;
    }

#endif

    void reset() // never throws in 1.30+
    {
        this_type().swap(*this);
    }

    template<class Y> void reset(Y * p) // Y must be complete
    {
        BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
        this_type(p).swap(*this);
    }

    template<class Y, class D> void reset( Y * p, D d )
    {
        this_type( p, d ).swap( *this );
    }

    template<class Y, class D, class A> void reset( Y * p, D d, A a )
    {
        this_type( p, d, a ).swap( *this );
    }

    template<class Y> void reset( shared_ptr<Y> const & r, T * p )
    {
        this_type( r, p ).swap( *this );
    }

    reference operator* () const // never throws
    {
        BOOST_ASSERT(px != 0);
        return *px;
    }

    T * operator-> () const // never throws
    {
        BOOST_ASSERT(px != 0);
        return px;
    }

    T * get() const // never throws
    {
        return px;
    }

// implicit conversion to "bool"
#include <boost/smart_ptr/detail/operator_bool.hpp>

    bool unique() const // never throws
    {
        return pn.unique();
    }

    long use_count() const // never throws
    {
        return pn.use_count();
    }

    void swap(shared_ptr<T> & other) // never throws
    {
        std::swap(px, other.px);
        pn.swap(other.pn);
    }

    template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const
    {
        return pn < rhs.pn;
    }

    template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const
    {
        return pn < rhs.pn;
    }

    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const
    {
        return pn.get_deleter( ti );
    }

    bool _internal_equiv( shared_ptr const & r ) const
    {
        return px == r.px && pn == r.pn;
    }

// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends. (Matthew Langston)

#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS

private:

    template<class Y> friend class shared_ptr;
    template<class Y> friend class weak_ptr;


#endif

    T * px;                     // contained pointer
    boost::detail::shared_count pn;    // reference counter

};  // shared_ptr
template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
{
    return a.get() == b.get();
}

template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
{
    return a.get() != b.get();
}

#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96

// Resolve the ambiguity between our op!= and the one in rel_ops

template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
{
    return a.get() != b.get();
}

#endif

template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b)
{
    return a.owner_before( b );
}

template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
{
    a.swap(b);
}

template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r)
{
    return shared_ptr<T>(r, boost::detail::static_cast_tag());
}

template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r)
{
    return shared_ptr<T>(r, boost::detail::const_cast_tag());
}

template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r)
{
    return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
}

// shared_*_cast names are deprecated. Use *_pointer_cast instead.

template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
{
    return shared_ptr<T>(r, boost::detail::static_cast_tag());
}

template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
{
    return shared_ptr<T>(r, boost::detail::dynamic_cast_tag());
}
template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
{
    return shared_ptr<T>(r, boost::detail::polymorphic_cast_tag());
}

template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
{
    BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
    return shared_static_cast<T>(r);
}

// get_pointer() enables boost::mem_fn to recognize shared_ptr

template<class T> inline T * get_pointer(shared_ptr<T> const & p)
{
    return p.get();
}

// operator<<

#if !defined(BOOST_NO_IOSTREAM)

#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )

template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
{
    os << p.get();
    return os;
}

#else

// in STLport's no-iostreams mode no iostream symbols can be used
#ifndef _STLP_NO_IOSTREAMS

# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
using std::basic_ostream;
template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
# else
template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
# endif
{
    os << p.get();
    return os;
}

#endif // _STLP_NO_IOSTREAMS

#endif // __GNUC__ < 3

#endif // !defined(BOOST_NO_IOSTREAM)

// get_deleter

#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
    ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
    ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )


// g++ 2.9x doesn't allow static_cast<X const *>(void *)
// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it

template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
{
    void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
    return const_cast<D *>(static_cast<D const *>(q));
}

#else

template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
{
    return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
}

#endif

// atomic access

#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)

template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ )
{
    return false;
}

template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p )
{
    boost::detail::spinlock_pool<2>::scoped_lock lock( p );
    return *p;
}

template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, memory_order /*mo*/ )
{
    return atomic_load( p );
}

template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
{
    boost::detail::spinlock_pool<2>::scoped_lock lock( p );
    p->swap( r );
}

template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
{
    atomic_store( p, r ); // std::move( r )
}

template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r )
{
    boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );

    sp.lock();
    p->swap( r );
    sp.unlock();

    return r; // return std::move( r )
}

template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, memory_order /*mo*/ )
{
    return atomic_exchange( p, r ); // std::move( r )
}

template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w )
{
    boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );

    sp.lock();

    if( p->_internal_equiv( *v ) )
    {
        p->swap( w );

        sp.unlock();

        return true;
    }
    else
    {
        shared_ptr<T> tmp( *p );

        sp.unlock();

        tmp.swap( *v );
        return false;
    }
}

template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, memory_order /*success*/, memory_order /*failure*/ )
{
    return atomic_compare_exchange( p, v, w ); // std::move( w )
}

#endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS)

// hash_value

template< class T > struct hash;

template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p )
{
    return boost::hash< T* >()( p.get() );
}

} // namespace boost

#endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)

#endif  // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED

42

http://www.boost.org/doc/libs/1_51_0/libs/smart_ptr/smart_ptr.htm


http://67.223.234.84/boost_doc/libs/smart_ptr/shared_ptr.htm


Introduction 簡介

shared_ptr 類模板存儲一個指向動態分配對像(一般是用 C++ new-expression 生成的)的指針。在最後一個 shared_ptr 所指向的對象被銷毀或重置時,要保證它所指向的對象被刪除。參見示例。

每一個 shared_ptr 都符合 C++ 標準庫的 CopyConstructible 和 Assignable 的必要條件,並因此能夠用於標準庫容器。因為提供了比較操作,因此 shared_ptr 可以和標準庫中的關聯式容器一起工作。

通常,一個 shared_ptr 不能正確地持有一個指向動態分配的數組的指針。關於那種用法請參見 shared_array。

因為在實現中使用了引用計數,shared_ptr實例的循環引用不會被回收。例如,如果 main() 持有一個指向 A 的 shared_ptr, A 又直接或間接持有一個指回 A 的 shared_ptr,A 的使用計數是 2。最初的 shared_ptr 析構後將導致一個使用計數為 1 的 A 被懸掛。使用 weak_ptr 以「打破循環」。

這個類模板被 T 參數化,T 是被指向的對象的類型。shared_ptr 和它的大多數成員函數對於 T 沒什麼要求,允許它是一個不完整類型,或者為 void。對 T 有附加要求的成員函數 (constructors, reset) 都明確地記錄在下面。

只要 T* 能被隱式地轉換到 U*,則 shared_ptr<T> 就能被隱式地轉換到 shared_ptr<U>。特別是,shared_ptr<T> 隱式轉換到 shared_ptr<T const>,當 U 是 T 的一個可訪問基類的時候,還能轉換到 shared_ptr<U>,以及轉換到 shared_ptr<void>。

shared_ptr 現在是 TR1(第一個 C++ 庫技術報告)的一部分。TR1 的最新草案可以在下述位置找到:

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1745.pdf (1.36Mb PDF)

這個實現與 TR1 規範一致,僅有的例外是它依然存在於名字空間 boost 中,而不是 std::tr1。
Best Practices 最佳實踐

一個簡單的近乎完全消滅內存洩露的方針是:總是使用一個已命名的智能指針變量接收 new 的結果。代碼中每一次出現 new 關鍵字都應該是如下形式:

shared_ptr<T> p(new Y);

當然,也可以用其它智能指針代替上面的 shared_ptr;T 是和 Y 相同的類型,或者是可作為參數傳遞給 Y 的構造函數即可。

如果你遵守這個方針,自然導致你不再需要顯式 deletes,try/catch 結構也將非常罕見。

避免使用匿名 shared_ptr 臨時變量去存儲內容,為了看到這樣做是如何的危險,請考慮下面的例子:

void f(shared_ptr<int>, int);
int g();

void ok()
{
    shared_ptr<int> p(new int(2));
    f(p, g());
}

void bad()
{
    f(shared_ptr<int>(new int(2)), g());
}

函數 ok 亦步亦趨地遵循了方針,相反 bad 構造了臨時的 shared_ptr 來代替,這就為內存洩漏留下了可乘之機。因為函數參數的求值順序是不確定的,new int(2) 首先被求值,g() 第二個是有可能的,如果 g 拋出一個異常,我們永遠也不可能到達 shared_ptr 的構造函數。關於這個問題的更多信息請參見 Herb Sutter 的對策(還有 這裡)。
Synopsis 概要

namespace boost {

  class bad_weak_ptr: public std::exception;

  template<class T> class weak_ptr;

  template<class T> class shared_ptr {

    public:

      typedef T element_type;

      shared_ptr(); // never throws
      template<class Y> explicit shared_ptr(Y * p);
      template<class Y, class D> shared_ptr(Y * p, D d);
      template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);
      ~shared_ptr(); // never throws

      shared_ptr(shared_ptr const & r); // never throws
      template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws
      template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);
      template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r);

      shared_ptr & operator=(shared_ptr const & r); // never throws 
      template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws
      template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);

      void reset(); // never throws
      template<class Y> void reset(Y * p);
      template<class Y, class D> void reset(Y * p, D d);
      template<class Y, class D, class A> void reset(Y * p, D d, A a);
      template<class Y> void reset(shared_ptr<Y> const & r, T * p); // never throws

      T & operator*() const; // never throws
      T * operator->() const; // never throws
      T * get() const; // never throws

      bool unique() const; // never throws
      long use_count() const; // never throws

      operator unspecified-bool-type() const; // never throws

      void swap(shared_ptr & b); // never throws
  };

  template<class T, class U>
    bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

  template<class T, class U>
    bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

  template<class T, class U>
    bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

  template<class T> void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws

  template<class T> T * get_pointer(shared_ptr<T> const & p); // never throws

  template<class T, class U>
    shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws

  template<class T, class U>
    shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws

  template<class T, class U>
    shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r); // never throws

  template<class E, class T, class Y>
    std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);

  template<class D, class T>
    D * get_deleter(shared_ptr<T> const & p);
}

Members 成員
element_type 元素類型

typedef T element_type;

    提供模板參數 T 的類型。

constructors 構造函數

shared_ptr(); // never throws

    作用:構造一個 empty 的 shared_ptr。

    後置條件:use_count() == 0 && get() == 0。

    拋出:無。

【這裡保證不拋出異常非常重要,因為 reset() 被指定使用缺省構造函數,這就意味著構造函數不必分配內存。】

template<class Y> explicit shared_ptr(Y * p);

    條件:p 必須可以被轉換到 T *。Y 必須是一個完整類型。表達式 delete p 必須是正常可用的,不能發生未定義行為,也不能拋出異常。

    作用:構造一個擁有指針 p 的 shared_ptr。

    後置條件:use_count() == 1 && get() == p。

    拋出:std::bad_alloc,或者一個由實現定義的當內存之外的某個資源無法獲得時的異常。

    異常安全:如果拋出一個異常,則調用 delete p。

    注意:p 必須是一個指向由 C++ new 表達式分配的對象的指針或者是 0。即使 p 是 0,後置條件中的 use count 也是 1,在一個值為 0 的指針上調用 delete 是無害的。

【這個構造函數被變成模板是為了記住被傳遞的實際的指針類型。析構函數可以針對同樣的指針,連同它的原始類型調用 delete,即使 T 沒有虛擬析構函數,或者是 void。

可選的侵入式的計數支持暴露了太多的實現細節,而且無法和 weak_ptr 很好地結合。當前實現使用了一個不同的機制,enable_shared_from_this 以解決 "shared_ptr from this" 問題。】

template<class Y, class D> shared_ptr(Y * p, D d);
template<class Y, class D, class A> shared_ptr(Y * p, D d, A a);

    條件:p 必須可變換為 T *。D 必須是 CopyConstructible(可拷貝構造)的。D 的拷貝構造函數和析構函數不能拋出異常。表達式 d(p) 必須是正常可用的,不能發生未定義行為,也不能拋出異常。A 必須是一個 Allocator(分配器),關於分配器的描述可參見 C++ 標準 20.1.5 (Allocator requirements)。

    作用:構造一個擁有指針 p 和刪除器 d 的 shared_ptr。第二個構造函數用 a 的一個拷貝分配內存。

    後置條件:use_count() == 1 && get() == p。

    拋出:std::bad_alloc,或者一個由實現定義的當內存之外的某個資源無法獲得時的異常。

    異常安全:如果拋出一個異常,則調用 d(p)。

    注意:在 p 指向的對象被刪除時,所存儲的 d 的拷貝被調用,並以所存儲的 p 的拷貝作為參數。

【custom deallocators(定制化釋放器)准許一個返回 shared_ptr 的工廠函數以將用戶隔離在它的內存分配策略之外。因為這個 deallocator(釋放器)不是類型的一部分,改變其分配策略不會破壞源代碼級或二進制級兼容性,也不需要客戶端重新編譯。例如,一個 "no-op" 釋放器返回一個指向靜態分配對象的 shared_ptr 是有用的,而其它變種卻允許用一個 shared_ptr 來包裝其它智能指針,以方便互操作性。

對 custom deallocators(定制化釋放器)的支持不會強加很大的負擔。其它 shared_ptr 特性依然需要 deallocator(釋放器)提供支持。

對 D 的拷貝構造函數不能拋出異常的需求來自於以值傳遞。如果拷貝構造函數拋出異常,指針就會洩漏。排除這一需求需要使用以 (const) reference((常)引用)傳遞。

以引用傳遞的主要問題在於它和 rvalues(右值)的相互影響。一個 const reference(常引用)可能還是會引起一次拷貝,並需要一個 const operator()。而一個 non-const reference(非常引用)根本不會綁定在一個右值上。解決這個問題的一個好的方案是 N1377/N1385 提案中的 rvalue reference(右值引用)。】

shared_ptr(shared_ptr const & r); // never throws
template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws

    作用:如果 r 為 empty,構造一個 empty shared_ptr,否則,構造一個帶有 r 的 shares ownership(共享所有權)的 shared_ptr。

    後置條件: get() == r.get() && use_count() == r.use_count()。

    拋出:無。

template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);

    作用:構造一個帶有 r 的 shares ownership(共享所有權)的 shared_ptr,並存儲 r 中所存儲指針的一個拷貝。

    後置條件:use_count() == r.use_count()。

    拋出:當 r.use_count() == 0 時,拋出 bad_weak_ptr。

    異常安全:如果拋出一個異常,構造函數將不起作用。

template<class Y> shared_ptr(std::auto_ptr<Y> & r);

    作用:構造一個 shared_ptr,就像存儲了一個 r.release() 的返回值的拷貝。

    後置條件:use_count() == 1。

    拋出:std::bad_alloc,或者一個由實現定義的當內存之外的某個資源無法獲得時的異常。

    異常安全:如果拋出一個異常,構造函數將不起作用。

【這個構造函數所得到的源 auto_ptr 是以引用傳遞的,而非以值傳遞,而且不能接收 auto_ptr 臨時變量。這是故意的,作為構造函數提出的強制保證,一個右值引用也可以解決這個問題。】
destructor 析構函數

~shared_ptr(); // never throws

    作用:

        如果 *this 為 empty,或者和其他 shared_ptr 實例共享所有權 (use_count() > 1),沒有副作用。
        否則,如果 *this 擁有一個指針 p 和一個刪除器 d,則調用 d(p)。
        否則,*this 擁有一個指針 p,則調用 delete p。

    拋出:無。

assignment 賦值

shared_ptr & operator=(shared_ptr const & r); // never throws
template<class Y> shared_ptr & operator=(shared_ptr<Y> const & r); // never throws
template<class Y> shared_ptr & operator=(std::auto_ptr<Y> & r);

    作用:等價於 shared_ptr(r).swap(*this)。

    返回:*this。

    注意:由臨時對象的構造和析構造成的使用計數的更新不被認為是可察覺的副作用,而實現可以自由地經由不同的手段達到其效果(以及隱含的保證),而不創建臨時變量。特別是,在下例中:

    shared_ptr<int> p(new int);
    shared_ptr<void> q(p);
    p = p;
    q = p;

    兩個賦值可能都是 no-op(什麼都不做)。

reset 重置

void reset(); // never throws

    作用:等價於 shared_ptr().swap(*this)。

template<class Y> void reset(Y * p);

    作用:等價於 shared_ptr(p).swap(*this)。

template<class Y, class D> void reset(Y * p, D d);

    作用:等價於 shared_ptr(p, d).swap(*this)。

template<class Y, class D, class A> void reset(Y * p, D d, A a);

    作用:等價於 shared_ptr(p, d, a).swap(*this)。

template<class Y> void reset(shared_ptr<Y> const & r, T * p); // 不拋出

    作用:等價於 shared_ptr(r, p).swap(*this).

indirection 間接引用

T & operator*() const; // never throws

    條件:所存儲的指針不能為 0。

    返回:一個引向所存儲的指針所指向的對象的引用。

    拋出:無。

T * operator->() const; // never throws

    條件:所存儲的指針不能為 0。

    返回:所存儲的指針。

    拋出:無。

get 取得

T * get() const; // never throws

    返回:所存儲的指針。

    拋出:無。

unique 唯一性

bool unique() const; // never throws

    返回:use_count() == 1。

    拋出:無。

    注意:unique() 可能比 use_count() 更快。如果你用 unique() 實現 copy on write(寫時拷貝),當所存儲的指針為 0 是,不要依賴於一個特定的值。

use_count 使用計數

long use_count() const; // never throws

    返回:與 *this 共享所有權的 shared_ptr 對像(包括 *this 在內)的數量,或者當 *this 為空時,一個不特定的非負值。

    拋出:無。

    注意:use_count() 達不到必要的效率。只用於調試和測試的目的。而不要用於產品代碼。

conversions 轉換

operator unspecified-bool-type () const; // never throws

    返回:一個未確定的值,在需要布爾值的上下文中,它等價於 get() != 0。

    拋出:無。

    注意:這一轉換操作符允許將 shared_ptr 對像用於需要布爾值的上下文中,就像 if (p && p->valid()) {}。實際目標類型通常是一個指向成員函數的指針,消除了很多隱式轉換的陷阱。

【到 bool 的轉換不僅僅是語法糖。它允許在使用 dynamic_pointer_cast 或 weak_ptr::lock 時,在條件中聲明 shared_ptrs。】
swap 交換

void swap(shared_ptr & b); // never throws

    作用:交換兩個智能指針中的內容。

    拋出:無。

Free Functions 自由函數
comparison 比較

template<class T, class U>
  bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

    返回:a.get() == b.get()。

    拋出:無。

template<class T, class U>
  bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

    返回:a.get() != b.get()。

    拋出:無。

template<class T, class U>
  bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b); // never throws

    返回:一個未確定值,以致於

        operator< 是一個嚴格意義上的 C++ 標準 25.3 [lib.alg.sorting] 中描述的 weak ordering(弱順序);
        等值關係通過 operator< 來定義,!(a < b) && !(b < a),在這種情況下,當且僅當兩個 shared_ptr 實例共享所有權或者都為空時,兩個 shared_ptr 相等。

    拋出:無。

    注意:允許 shared_ptr 對像在關聯式容器中作為鍵值使用。

【因為兼容性和合法性的原因,Operator< 比 std::less 的特化版本更優先被選用,因為 std::less 需要返回一個 operator< 的結果,而當沒有提供謂詞時,許多標準算法在比較中使用 operator< 來代替 std::less。組合對象,比如 std::pair,也根據它們所包含的子對象的 operator< 來實現它們的 operator<。

其餘的比較操作符被故意省略。】
swap 交換

template<class T>
  void swap(shared_ptr<T> & a, shared_ptr<T> & b); // never throws

    作用:等價於 a.swap(b)。

    拋出:無。

    注意:與 std::swap 的接口匹配。為泛型編程提供幫助。

【swap 被定義在和 shared_ptr 同樣的名字空間中,這是當前提供一個讓標準庫有機會使用的 swap 函數的僅有的合法方法。】
get_pointer 取得指針

template<class T>
  T * get_pointer(shared_ptr<T> const & p); // never throws

    返回:p.get()。

    拋出:無。

    注意:為泛型編程提供幫助,用於 mem_fn。

static_pointer_cast

template<class T, class U>
  shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r); // never throws

    條件:表達式 static_cast<T*>(r.get()) 必須正常可用。

    返回:如果 r 為 empty,返回一個 empty shared_ptr<T>;否則,返回一個存儲 static_cast<T*>(r.get()) 的拷貝並和 r 共享所有權的 shared_ptr<T> 對象。

    拋出:無。

    注意:表面上看似乎等價的表達式

    shared_ptr<T>(static_cast<T*>(r.get()))

    因為試圖刪除同樣的對象兩次,而最終陷入未定義行為。

const_pointer_cast

template<class T, class U>
  shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r); // never throws

    條件:表達式 const_cast<T*>(r.get()) 必須正常可用。

    返回:如果 r 為 empty,返回一個 empty shared_ptr<T>;否則,返回一個存儲 const_cast<T*>(r.get()) 的拷貝並和 r 共享所有權的 shared_ptr<T> 對象。

    拋出:無。

    注意:表面上看似乎等價的表達式

    shared_ptr<T>(const_cast<T*>(r.get()))

    因為試圖刪除同樣的對象兩次,而最終陷入未定義行為。

dynamic_pointer_cast

template<class T, class U>
  shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r);

    條件:表達式 dynamic_cast<T*>(r.get()) 必須正常可用,而且它的行為已被定義。

    返回:

        當 dynamic_cast<T*>(r.get()) 返回一個非 0 值,則返回一個存儲它的拷貝並和 r 共享所有權的 shared_ptr<T> 對像;
        否則,返回一個 empty shared_ptr<T> 對象。

    拋出:無。

    注意:表面上看似乎等價的表達式

    shared_ptr<T>(dynamic_cast<T*>(r.get()))

    因為試圖刪除同樣的對象兩次,而最終陷入未定義行為。

operator<<

template<class E, class T, class Y>
    std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p);

    作用:os << p.get();。

    返回:os。

get_deleter

template<class D, class T>
    D * get_deleter(shared_ptr<T> const & p);

    返回:如果 *this 擁有一個類型為 D 的刪除器 d,則返回 &d;否則返回 0。

Example 示例

來看一個完整的示例程序 shared_ptr_example.cpp。這個程序創建了一個 shared_ptr 對象的 std::vector 和 std::set。

注意,在容器被填充之後,一些 shared_ptr 對象的使用計數為 1,而不是 2,這是因為 set 是一個 std::set 而不是 std::multiset,而這樣就不能包含重複的條目。此外,當 push_back 和 insert 容器操作執行的次數不同,使用計數可能會更高。還有更複雜的,容器操作在多種情況下都可能拋出異常。在這個示例程序中的內存管理和異常處理都很正常,而沒有讓智能指針成為一場噩夢。
Handle/Body Idiom Handle/Body 慣用法

shared_ptr 的一個慣常用法是實現 handle/body(也稱為 pimpl)慣用法,以避免在頭文件中暴露身體(實現)。

shared_ptr_example2_test.cpp 示例程序包含一個頭文件 shared_ptr_example2.hpp,其中使用了一個指向一個完整類型的 shared_ptr<> 來隱藏實現。成員函數的實例化要求在 shared_ptr_example2.cpp 實現文件中存在完整類型。注意這裡不需要顯示的析構函數。不像 ~scoped_ptr,~shared_ptr 不需要 T 是一個完整類型。
Thread Safety 線程安全

shared_ptr 對像提供與內建類型一樣的線程安全級別。一個 shared_ptr 實例可以同時被多個線程「讀」(僅使用不變操作進行訪問)。不同的 shared_ptr 實例可以同時被多個線程「寫入」(使用類似 operator= 或 reset 這樣的可變操作進行訪問)(即使這些實例是拷貝,而且共享下層的引用計數)。

任何其它的同時訪問的結果會導致未定義行為。

示例:

shared_ptr<int> p(new int(42));

//--- Example 1 ---

// thread A
shared_ptr<int> p2(p); // reads p

// thread B
shared_ptr<int> p3(p); // OK, multiple reads are safe

//--- Example 2 ---

// thread A
p.reset(new int(1912)); // writes p

// thread B
p2.reset(); // OK, writes p2

//--- Example 3 ---

// thread A
p = p3; // reads p3, writes p

// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write

//--- Example 4 ---

// thread A
p3 = p2; // reads p2, writes p3

// thread B
// p2 goes out of scope: undefined, the destructor is considered a "write access"

//--- Example 5 ---

// thread A
p3.reset(new int(1));

// thread B
p3.reset(new int(2)); // undefined, multiple writes



從 Boost 版本 1.33.0 開始,shared_ptr 在以下平台上使用了 lock-free 實現:

    GNU GCC on x86 or x86-64;
    GNU GCC on IA64;
    Metrowerks CodeWarrior on PowerPC;
    GNU GCC on PowerPC;
    Windows.

如果你的程序是單線程的,而且在它的缺省配置中沒有連接任何可能使用了 shared_ptr 的庫,你可以在項目基準中 #define 宏 BOOST_SP_DISABLE_THREADS 以轉換到普通的非原子的引用計數更新。

(在部分(而非全部)編譯單元中定義 BOOST_SP_DISABLE_THREADS 在技術上是對單一定義規則和未定義行為的觸犯。然而,實現會盡其所能滿足那些提出使用非原子更新的編譯單元的要求。但是,沒有任何保證。)

你可以定義宏 BOOST_SP_USE_PTHREADS 以避開特定平台的 lock-free 實現,並退回到普通的基於 pthread_mutex_t 的代碼。
Frequently Asked Questions 常見問題

問:有幾種共享指針的變化,反映不同的權衡,為什麼智能指針庫僅提供一種單一的實現?能夠用每一種類型做試驗以發現最適合手邊工作的那一種不是非常有好處的嗎?

答:shared_ptr 的一個重要目標是提供一個標準的共享所有權指針。對於穩定的庫接口來說,單一指針類型是很重要的,因為不同的共享指針一般無法互操作,例如,一個 reference counted pointer(引用計數指針)(用於庫 A)不能和一個 linked pointer(連接指針)(用於庫 B)共享所有權。

問:shared_ptr 為什麼沒有用來提供特性或規則的模板參數以允許廣泛的用戶定制性?

答:參數化會阻礙用戶。shared_ptr 模板小心謹慎地精工細作以滿足通用需求,而沒有大量的參數化。有朝一日,可能會有人發明可配置性很高的智能指針,而且很易於使用並難於犯錯。到那時,shared_ptr 會成為為各種各樣的應用而選擇的智能指針。(那些對基於策略的智能指針感興趣的人可以閱讀 Andrei Alexandrescu 寫的 Modern C++ Design。)

問:我不確定。缺省參數可以用於那些需要隱藏複雜度的地方。再問一次,為什麼不規則化?

答:模板參數影響類型。參見上面第一個問題的回答。

問:shared_ptr 為什麼不用鏈表實現?

答:鏈表實現的好處不足以抵消一個額外的指針所增加的開銷。參見 timings 頁面。另外,讓一個鏈表實現線程安全的代價太大了。

問:shared_ptr(或其它任何一個 Boost 智能指針)不提供一個到 T* 的自動轉換?

答:自動轉換被認為更易於導致錯誤。

問:shared_ptr 為什麼提供 use_count()?

答:為了幫助寫測試用例和調試顯示。一個祖先類有 use_count(),它對於在一個複雜的項目中追蹤 bugs 並切斷循環依賴是非常有用的。

問:為什麼 shared_ptr 不指定複雜度要求?

答:因為複雜度要求限制了實現,並且使規範更複雜,對於 shared_ptr 的用戶卻沒有明顯的好處。例如,如果不得不符合嚴厲的複雜度要求,錯誤檢查的實現可能會變得不一致。

問:為什麼 shared_ptr 不提供一個 release() 函數?

答:shared_ptr 不能放棄所有權除非它是 unique(),因為其它拷貝仍然可以銷毀這個對象。

考慮:

    shared_ptr<int> a(new int);
    shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2

    int * p = a.release();

    // Who owns p now? b will still call delete on it in its destructor.

此外,當源 shared_ptr 可能帶有一個定制化的刪除器時,release() 返回的指針很難可靠地被釋放。

問:為什麼 operator->() 是 const 的,而它的返回值卻是指向元素類型的 non-const 指針?

答:淺拷貝指針,包括裸指針,一般不會傳遞常量性。當你能夠總是從一個 const 指針得到一個 non-const 指針,並繼而通過它改變那個對象的時候,還是有一點兒意義的。shared_ptr 是「盡可能接近而不重合裸指針」。

43
XD 一定要休息了....

有可能是我自己在異步IO下長指標造成的錯亂.

晚一點利用 BOOST 內建的智慧型指標 shared_ptr 再來玩一次看看.


44
@@"

全部重新編譯後....

並且重新載入 ldconfig .

又完全不會了~~給它壓測一晚看看吧~XD....

是怎樣~

45
0x2abe54002e90 是被我丟到 map 裡的 指標.

拿它出來用 並且 close socket 不會有問題...

但是 寫程式 跑了 幾十分後才會出現這個問題.....

哈~把測試程式打進去~~跑了很久~都不會了~果然解決了~~

C++11 << 造成 1.50 版本不相容.

XD .....

用太新的技術也中槍~~~~@@

才剛講完~~就跳了~ 不過錯誤的訊息不一樣了~而且少很多錯誤~~有進步~XD.

[root@FIEND wge_server]# gdb sbin/wge core.20276
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-56.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/cpp/wge_server/sbin/wge...(no debugging symbols found)...done.
[New Thread 20278]
[New Thread 20276]
[New Thread 20277]
[New Thread 20279]
Missing separate debuginfo for /usr/local/wge/server/boost/lib/libboost_system.so.1.51.0
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/43/e38b856af532331942a23fd0cfd05c3a7eb6b2
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libPhpFpm.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/7b/cb561cb29f74b1fd8f6121b1ef8b24babe5890
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libWgeBase64.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/1b/1cd9c7370849727662953e57da8d4e5c0e7c78
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libWgeJsoncpp.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/b8/1f4d99f40ef14d4dbb56900669dad627d4f09d
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libZlib.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/6f/50ef6e38d3cb1e25ba8b37d6bce700e6ee6d0f
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libWgeOpenssl.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/a1/6668595410ed1f78e46ce2b00168c58107f102
Missing separate debuginfo for /usr/local/wge/server/poco/lib/libPocoFoundation.so.12
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/9b/d1532f5e378a14a2cd3d2ba460fd79ebae579b
Missing separate debuginfo for
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/74/22987f6cfa699f465b0327139aac3fdac4a838
Reading symbols from /usr/local/wge/server/boost/lib/libboost_system.so.1.51.0...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/boost/lib/libboost_system.so.1.51.0
Reading symbols from /usr/local/wge/server/wge/lib/libPhpFpm.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libPhpFpm.so
Reading symbols from /usr/local/wge/server/wge/lib/libWgeBase64.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libWgeBase64.so
Reading symbols from /usr/local/wge/server/wge/lib/libWgeJsoncpp.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libWgeJsoncpp.so
Reading symbols from /usr/local/wge/server/wge/lib/libZlib.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libZlib.so
Reading symbols from /usr/local/wge/server/wge/lib/libWgeOpenssl.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libWgeOpenssl.so
Reading symbols from /usr/lib64/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /lib64/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/librt.so.1
Reading symbols from /usr/local/wge/server/poco/lib/libPocoFoundation.so.12...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/poco/lib/libPocoFoundation.so.12
Reading symbols from /usr/lib64/libcrypto.so.10...(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/libcrypto.so.10
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /lib64/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/libdl.so.2
Reading symbols from /lib64/libz.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libz.so.1
Core was generated by `./sbin/wge'.
Program terminated with signal 11, Segmentation fault.
#0  0x000000000040d19b in boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::close() ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.el6_3.3.x86_64 libgcc-4.4.6-4.el6.x86_64 libstdc++-4.4.6-4.el6.x86_64 openssl-1.0.0-25.el6_3.1.x86_64 zlib-1.2.3-27.el6.x86_64
(gdb) bt
#0  0x000000000040d19b in boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::close() ()
#1  0x00000000004148f3 in session::loginChk() ()
#2  0x0000000000415020 in session::readClientRequest() ()
#3  0x0000000000409455 in boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long)
    ()
#4  0x000000000040b752 in boost::asio::detail::epoll_reactor::descriptor_state::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) ()
#5  0x000000000040e885 in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
#6  0x000000000040484e in startServer() ()
#7  0x0000003e978b6470 in ?? () from /usr/lib64/libstdc++.so.6
#8  0x000000342be07851 in start_thread () from /lib64/libpthread.so.0
#9  0x000000342b6e76dd in clone () from /lib64/libc.so.6
(gdb) q


XD!!!!!

休息一下~~@@ 想想別的解法~XD.


46
0x2abe54002e90 是被我丟到 map 裡的 指標.

拿它出來用 並且 close socket 不會有問題...

但是 寫程式 跑了 幾十分後才會出現這個問題.....

哈~把測試程式打進去~~跑了很久~都不會了~果然解決了~~

C++11 << 造成 1.50 版本不相容.

XD .....

用太新的技術也中槍~~~~@@


47
0x2abe54002e90 是被我丟到 map 裡的 指標.

拿它出來用 並且 close socket 不會有問題...

但是 寫程式 跑了 幾十分後才會出現這個問題.....





48
XD ......  一定要這麼難搞...

[root@FIEND wge_server]# gdb sbin/wge core.5472

GNU gdb (GDB) Red Hat Enterprise Linux (7.2-56.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/cpp/wge_server/sbin/wge...done.
[New Thread 5474]
[New Thread 5475]
[New Thread 5472]
[New Thread 5473]
Missing separate debuginfo for /usr/local/wge/server/boost/lib/libboost_system.so.1.50.0
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/c3/337ba893c244011a9007b761af66b82fb5af7a
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libPhpFpm.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/7b/cb561cb29f74b1fd8f6121b1ef8b24babe5890
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libWgeBase64.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/1b/1cd9c7370849727662953e57da8d4e5c0e7c78
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libWgeJsoncpp.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/b8/1f4d99f40ef14d4dbb56900669dad627d4f09d
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libZlib.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/6f/50ef6e38d3cb1e25ba8b37d6bce700e6ee6d0f
Missing separate debuginfo for /usr/local/wge/server/wge/lib/libWgeOpenssl.so
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/a1/6668595410ed1f78e46ce2b00168c58107f102
Missing separate debuginfo for /usr/local/wge/server/poco/lib/libPocoFoundation.so.12
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/9b/d1532f5e378a14a2cd3d2ba460fd79ebae579b
Missing separate debuginfo for
Try: yum --disablerepo='*' --enablerepo='*-debug*' install /usr/lib/debug/.build-id/74/22987f6cfa699f465b0327139aac3fdac4a838
Reading symbols from /usr/local/wge/server/boost/lib/libboost_system.so.1.50.0...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/boost/lib/libboost_system.so.1.50.0
Reading symbols from /usr/local/wge/server/wge/lib/libPhpFpm.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libPhpFpm.so
Reading symbols from /usr/local/wge/server/wge/lib/libWgeBase64.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libWgeBase64.so
Reading symbols from /usr/local/wge/server/wge/lib/libWgeJsoncpp.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libWgeJsoncpp.so
Reading symbols from /usr/local/wge/server/wge/lib/libZlib.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libZlib.so
Reading symbols from /usr/local/wge/server/wge/lib/libWgeOpenssl.so...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/wge/lib/libWgeOpenssl.so
Reading symbols from /usr/lib64/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /lib64/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/librt.so.1
Reading symbols from /usr/local/wge/server/poco/lib/libPocoFoundation.so.12...(no debugging symbols found)...done.
Loaded symbols for /usr/local/wge/server/poco/lib/libPocoFoundation.so.12
Reading symbols from /usr/lib64/libcrypto.so.10...(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/libcrypto.so.10
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /lib64/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/libdl.so.2
Reading symbols from /lib64/libz.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/libz.so.1
Core was generated by `./sbin/wge'.
Program terminated with signal 11, Segmentation fault.
#0  0x000000000040f3cb in close (this=0x2abe54002e90) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/reactive_socket_service_base.ipp:103
103             (impl.state_ & socket_ops::possible_dup) == 0);
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.el6_3.3.x86_64 libgcc-4.4.6-4.el6.x86_64 libstdc++-4.4.6-4.el6.x86_64 openssl-1.0.0-25.el6_3.1.x86_64 zlib-1.2.3-27.el6.x86_64
(gdb) bt
#0  0x000000000040f3cb in close (this=0x2abe54002e90) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/reactive_socket_service_base.ipp:103
#1  close (this=0x2abe54002e90) at /usr/local/wge/server/boost/include/boost/asio/stream_socket_service.hpp:151
#2  boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::close (this=0x2abe54002e90) at /usr/local/wge/server/boost/include/boost/asio/basic_socket.hpp:309
#3  0x00000000004147d3 in session::loginChk (this=0x2abe54002e10) at ./src/wge.cpp:444
#4  0x0000000000414f00 in session::readClientRequest (this=0x2abe54002e10) at ./src/wge.cpp:606
#5  0x0000000000409545 in call<boost::shared_ptr<session>, boost::system::error_code const, unsigned long> (owner=<value optimized out>, base=<value optimized out>)
    at /usr/local/wge/server/boost/include/boost/bind/mem_fn_template.hpp:271
#6  operator()<boost::shared_ptr<session> > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/mem_fn_template.hpp:286
#7  operator()<boost::_mfi::mf2<void, session, const boost::system::error_code&, long unsigned int>, boost::_bi::list2<const boost::system::error_code&, const long unsigned int&> > (owner=<value optimized out>,
    base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/bind.hpp:392
#8  operator()<boost::system::error_code, long unsigned int> (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/bind/bind_template.hpp:102
#9  operator() (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/bind_handler.hpp:118
#10 asio_handler_invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, boost::system::error_code, unsigned long> > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/handler_invoke_hook.hpp:64
#11 invoke<boost::asio::detail::binder2<boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> >, boost::system::error_code, unsigned long>, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > > (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/handler_invoke_helpers.hpp:39
#12 boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1, boost::_bi::bind_t<void, boost::_mfi::mf2<void, session, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<boost::shared_ptr<session> >, boost::arg<1> (*)(), boost::arg<2> (*)()> > >::do_complete (owner=<value optimized out>, base=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/reactive_socket_recv_op.hpp:110
#13 0x000000000040e8f2 in complete (owner=0x2abe54000910, base=<value optimized out>, ec=..., bytes_transferred=<value optimized out>) at /usr/local/wge/server/boost/include/boost/asio/detail/task_io_service_operation.hpp:37
#14 boost::asio::detail::epoll_reactor::descriptor_state::do_complete (owner=0x2abe54000910, base=<value optimized out>, ec=..., bytes_transferred=<value optimized out>)
    at /usr/local/wge/server/boost/include/boost/asio/detail/impl/epoll_reactor.ipp:650
#15 0x0000000000410a15 in complete (this=0x2abe54000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/task_io_service_operation.hpp:37
#16 do_run_one (this=0x2abe54000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/task_io_service.ipp:394
#17 boost::asio::detail::task_io_service::run (this=0x2abe54000910, ec=...) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/task_io_service.ipp:146
#18 0x0000000000404c2e in run () at /usr/local/wge/server/boost/include/boost/asio/impl/io_service.ipp:59
#19 startServer () at ./src/wge.cpp:864
#20 0x0000003e978b6470 in ?? () from /usr/lib64/libstdc++.so.6
#21 0x000000342be07851 in start_thread () from /lib64/libpthread.so.0
#22 0x000000342b6e76dd in clone () from /lib64/libc.so.6
(gdb) q



TRACE 到 :

#0  0x000000000040f3cb in close (this=0x2abe54002e90) at /usr/local/wge/server/boost/include/boost/asio/detail/impl/reactive_socket_service_base.ipp:103

跑到 官方看 :

https://svn.boost.org/trac/boost/ticket/7275

@@"

C++11 會造成 103 行的錯誤... 沒錯我也是用 C++11 XD ...

好新的BUG 12天前~


##########

目前正在安裝 1.51 版...

看起來 1.51 修正了很多 c++11  的問題.

http://www.boost.org/users/history/version_1_51_0.html

New Libraries

    Context: Context switching library, from Oliver Kowalke.

Updated Libraries

    Algorithm:
        Fixed is_sorted_until ; now matches the c++11 standard behavior on ranges with duplicate values.
        Added range support for the rest of the search algorithms.
        unhex now uses Boost.Exception to signal bad input.
    Asio:
        Fixed an incompatibility between ip::tcp::iostream and C++11 (#7162).
        Decorated GCC attribute names with underscores to prevent interaction with user-defined macros (#6415).
        Added missing #include <cctype>, needed for some versions of MinGW.
        Changed to use gcc's atomic builtins on ARM CPUs, when available (#7140).
        Changed strand destruction to be a no-op, to allow strand objects to be destroyed after their associated io_service has been destroyed.
        Added support for some newer versions of glibc which provide the epoll_create1() function but always fail with ENOSYS (#7012).
        Changed the SSL implementation to throw an exception if SSL engine initialisation fails (#6303).
        Fixed another regression in buffered_write_stream (#6310).
        Implemented various minor performance improvements, primarily targeted at Linux x86 and x86-64 platforms.
    Config:
        Deprecated a whole bunch of macros that were c++11 specific, but not named to show that they were c++11 specific. Made new macros with better names, and paired the old macros with the new ones. Updated the documentation to list the deprecated macros.
    Chrono:
        #6918 Boost Chrono compilation failure on HP uX due to undefined pthread_getcpuclockid.
        #6241 boost::chrono compilation problems without std::wstring support.
        #6987 Documentation & C++11.
        #7041 time_point.hpp depends on Boost.System.
        #7042 Avoiding time_point and duration dependency on time.h and CLOCK_REALTIME.
        #7058 Make it work when BOOST_NO_EXCEPTIONS is defined.
        #7069 Misspellings in clock_string<thread_clock>.
        #7081 WinError.h capitalization in boost/detail/win/basic_types.hpp.
    Geometry:
        points accessed through a pointer (e.g. in a linestring) should now be specialized without the pointer. In previous versions a type my_point used like linestring<my_point*> had to be specalized like: template<> struct tag<my_point*>. Now the library itself removes the pointer before calling the traits class, so now it should be like: template<> struct tag<my_point>
        intersection was sometimes wrong for integer points, fixed
        documentation, order of parameters in simplify was wrong, fixed
        7030 spherical distance, fixed (by patch of Karsten Ahnert)
    Graph:
        Refactored support for internal and bundled properties in Boost.Graph-provided graph types, and cleaned up named parameter functionality:
            Enabled old-style (non-bundled) internal properties in compressed_sparse_row_graph.
            Bundled properties should work correctly for all graph types and adaptors.
        Bugs fixed:
            #6993: Typo Bundled Properties document
            #7002: Problem with initialization of CSR bidirectional graph
            #7023: Enclose internal type graphml_reader in anonymous namespace
            Other bugs and warnings not in Trac
    Hash:
        Support the standard smart pointers.
        hash_value now implemented using SFINAE to avoid implicit casts to built in types when calling it.
        Updated to use the new config macros.
    Lexical cast:
        Better performance, less memory usage for boost::array<character_type, N> and std::array<character_type, N> conversions.
        Fixed bug with volatile input parameter #7157.
    Math:
        Updated to use the new config macros.
    MSM:
        Support for boost::any http://www.boost.org/doc/libs/1_51_0/libs/msm/doc/HTML/ch03s03.html#any-event or kleene http://www.boost.org/doc/libs/1_51_0/libs/msm/doc/HTML/ch03s04.html#kleene-event as acceptable events
        Bugfix: compiler error with fsm internal table and none (compound) event.
        Bugfix: euml::defer_ leading to stack overflow.
    Proto:
        Proto transforms get pseudo-parameter pack expansion support for unpacking expressions. See the Release Notes for more information.
    Ratio:
        #7075 Workaround for error: the type of partial specialization template parameter constant "n1" depends on another template parameter.
    Regex:
        Updated to use the new config macros.
    Thread:
        #4258 Linking with boost thread does not work on mingw/gcc 4.5.
        #4885 Access violation in set_tss_data at process exit due to invalid assumption about TlsAlloc.
        #6931 mutex waits forwever with Intel Compiler and /debug:parallel
        #7044 boost 1.50.0 header missing.
        #7052 Thread: BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 only masks thread::operator==, thread::operator!= forward declarations, not definitions.
        #7066 An attempt to fix current_thread_tls_key static initialization order.
        #7074 Multiply defined symbol boost::allocator_arg.
        #7078 Trivial 64-bit warning fix on Windows for thread attribute stack size
        #7089 BOOST_THREAD_WAIT_BUG limits functionality without solving anything
    Unordered:
        Fix construction/destruction issue when using a C++11 compiler with a C++03 allocator (#7100).
        Remove a try..catch to support compiling without exceptions.
        Adjust SFINAE use to try to supprt g++ 3.4 (#7175).
        Updated to use the new config macros.
    Wave:
        See the Changelog for details.
    xpressive:
        Work around buggy wide ctype facet on cygwin and mingw.
        Work around absence of __isctype on some glibc implementations.
        op::as shouldn't assume string::iterator != char*.
        Fix assertion in cpp_regex_traits on libc++, thanks to John Fletcher.

Compilers Tested

Boost's primary test compilers are:

    Linux:
        GCC: 4.2.4, 4.3.4, 4.4.3, 4.5.3, 4.6.2, 4.7
        GCC, C++11 mode: 4.3.4, 4.4.3, 4.5.3, 4.6.2
        Intel: 11.1, 12.0, 12.1
        LLVM Clang 2.8
    OS X:
        GCC: 4.4
        GCC, C++11 mode: 4.4
        Intel: 11.1, 12.0
    Windows:
        GCC, mingw: 4.4.0, 4.4.7, 4.5.4, 4.6.3
        Visual C++: 8.0, 9.0, 10.0
    FreeBSD:
        GCC: 4.2.1, 32 and 64 bit

Boost's additional test compilers include:

    Linux:
        Clang: from subversion
        LLVM Clang: 3.0
        GCC: 4.2.4, 4.3.4, 4.4.4, 4.4.7, 4.5.3, 4.6.2, 4.6.3, 4.7.0, 4.7.1
        GCC, C++11 mode: 4.3.4, 4.4.4, 4.5.3, 4.6.3
        pgCC: 11.9
        Intel: 10.1, 11.1, 12.0, 12.1
        Visual Age: 10.1
    OS X:
        Clang: from subversion
        Clang, C++11 mode: from subversion
        Intel: 11.1, 12.0
        GCC: 4.4
        GCC, C++11 mode: 4.4
    Windows:
        Visual C++: 8.0, 9.0, 10.0
        GCC, mingw: 4.4.0, 4.6.3, 4.7.0
    AIX:
        IBM XL C/C++ Enterprise Edition: V12.1.0.0
    FreeBSD:
        GCC: 4.2.1, 32 and 64 bit
    Solaris:
        Sun: 5.10



49

越南 網路是 亞太地區目前成長速度較快的國家.

使用人口現在世界排行 18 名.

骨幹的佈建和大型的網路系統建設應該不差.

情況不會像泰國那麼糟....

之前泰國還水災.... @@ " 很整人.

而且泰國之前的網路品質很糟.


50
把 SOCKET 指標 存在記憶體容器後.

我發現可以自由的控制迴路何時要啟動.

何時要關閉.

假如 有使用者離開一陣子沒有操作 , 還可以放一支 THREAD 在背後檢查是不是該 清掉沒人用的迴路.

如果有使用者在連線之下 , 重新驗證登入條件 , 還可以直接把上次的登入的迴路全部淦掉.

超歡樂的.



51

難怪之前成天給我放茫....原來都在玩這個.

我也偷偷托人買了一組了 XD @@"

要敗一起敗~~

52
前陣子公司的大陸子公司的一堆工程師都在給我玩 Embedded .

害我差點 發文對子公司 工程部 下 Embedded 禁令.



問他們玩什麼玩那麼兇.

我忍不住去 淘寶看了一下 @@...

啊娘喂~難怪 玩那麼兇 , 真的東西好多.

我看了都手養的要命了!!!!

http://search.taobao.com/search?spm=a230r.1.10.284&q=android+%BF%AA%B7%A2%B0%E5&atype=b&filterFineness=2&newpre=null&s=280#J_FilterTabBar

最哭腰的是...

http://item.taobao.com/item.htm?spm=a230r.1.10.36&id=13860057260   <<< 明目張膽....大補帖...


影音教學.
原始碼
教學文件.
全部都有....

在那裡沒有版權問題 @@.....XD.........



53
又補了一佪邏輯.

在 ACCEPT 完  , 接下去 多一個 TCP 請求端的 CLIENT 連線端口的第一次 發送請求的確認.

如果丟出去沒有人回應 , 就直接中斷 異步 IO 的單一用戶的 請求.

來防止 , 有一些自以為網路很利害的小朋友 抓了一些TCP攻擊工具 ,  丟了就跑 害 SERVER 白做工.

有點像 有人按你家門鈴 你會先確認 , 按門鈴的人有沒有站在門口 , 跟他說一句話 看看有沒有反應 , 有的話才去樓下接他.

如果是 鄰居的死小孩按完就跑 , 就不用理它.

加強 安全性 , 降低 洪水攻擊 的負擔 .

這架構 好多變化....... 真爽 ~~

樓上的 , 圖己改.

自~HIGH~好久 @@"     .........

這篇文章議題應該 CLOSE 掉了.


下個 ENDING :

以前我們公司有個很會寫 網路層分位的高手 .

可惜他得了一場大病 前幾年 升天了.

以前雖然常吵架 , 但是現在好想念他....

他一定可以給我更好的建議~~

如果剛好也要做類似設計的請跳出來一起交流.....

潛水去~~等下次遇到問題再來這報到...

可惡還沒完!! 本來以為結案了.

我在 TRACE 封包時 , 發現一個大 BUG.

如果用戶是正常 離開 所有開放給這個用戶的異步迴路會自動被切斷.

如果用戶不是正常離開 , 但是它己經完成一開始的交易認證機制.

偶爾會讓 迴路死在裡面沒有主人 但是它還在跑.

看來還是要做一個 容器來監控每一個迴路的生命週期.

背後自己把迴路給淦掉.

省資源 想破頭了.....

另外做了 MAP 的個開關.

http://phorum.study-area.org/index.php/topic,67607.msg332764.html#new

在使用者完成驗證後 才會同意打開 5,6 迴路.

當使用者離開或者是重覆做驗證的動作.

系統會強迫性的把 沒用到的 連線及迴路全部強制關閉.




54
#include <iostream>
#include <limits>
#include <map>
using std::cout;
using std::endl;
using std::map;

class Room_Data
{
      public:
             Room_Data() {cout<<"Construct"<<endl;}
             ~Room_Data() {cout<<"Destruct"<<endl;}
             char*        name;
             int          vnum;
};

int main()
{
    Room_Data *pRoom;
    pRoom = new Room_Data;
    pRoom->vnum = 2400;
   
    map<int, Room_Data> rMap;
    map<int, Room_Data>::reverse_iterator iter;
   
    rMap[pRoom->vnum] = *pRoom;
   
    for ( iter = rMap.rbegin() ; iter != rMap.rend(); iter++ )
    {
        cout<<iter->second.vnum<<endl;
        }
    cout<<pRoom->vnum<<endl;
    cout << "Press ENTER to quit." << std::flush;
    std::cin.ignore( std::numeric_limits <std::streamsize> ::max(), '\n' );
    return 0;
}


實驗一下..... 這麼好用 >_<" 不知在異步 IO 下 可不可以拿來做切換器......


哇哈哈~~好好玩....


        tcp::socket socket_;    <<  指定一個 SOCKET 物件.
        tcp::socket *psocket;   <<< 指定一個 指標

再把 psocket = &socket_ ;  SOCKET 物件的位址丟給指標.

然後把指標 放進 MAP

再從MAP 拿出來用.

可以 配合 SESSION 來決定要強迫那個使用者斷線.

好好玩~~



55
如果你不喜歡常常被錢軟整

可以使用 第三方包好的套件來串你要的功能 , 問題會比較少.

因為第三方 己經幫你在 包裝套件的核心部份把問題都解決掉了.


推薦你用 JQUERY  相容的瀏覽器版本較多.

但是不支援 IE6 以下的版本.




56

先利用  alert() 去判斷 .

credit = document.getElementById('credit')

的 credit 有沒有抓到東西.

alert(credit) ;

把 JS 的位置放在 ELEMENT 上指定 OBJECT ID 的 HTML CODE 下.


看看 credit 用 ALERT 吐出來的是什麼內容.




可以了 非常感謝你

我把 credit = document.getElementById('credit') 這行 拉到

function show_credit(obj){ }  上面就 可以了

雖然IE還是有錯誤  但可以正常隱藏跟顯示

然後我把 credit = 都去掉 只剩下

document.getElementById('credit') 就 ok了

(不知道原本這語法是有啥問題 把getElement到的東西存到credit變數不行嗎?)

引用
我把 credit = document.getElementById('credit') 這行 拉到

function show_credit(obj){ }  上面就 可以了

直譯式語言 要先宣告才能用.

不像編譯式的  , 宣告位置可以放在 執行位置下面.

你的CODE 犯了這個錯.

學會用 ALERT 去 DEBUG 速度就快多了.

#####################


IE8 的錯誤訊息.... 我也不知道~AP 層的瀏覽器環境很亂 一直都有統一的格式 W3C 規範~

但是錢軟很愛亂改東西 , 而且不喜歡 遵守 W3C 的規範.

尤其是每次大改版 都不能上下相容.

我年輕的時候 為了錢軟 常常加班找問題........

習慣就好...


57

先利用  alert() 去判斷 .

credit = document.getElementById('credit')

的 credit 有沒有抓到東西.

alert(credit) ;

把 JS 的位置放在 ELEMENT 上指定 OBJECT ID 的 HTML CODE 下.

看看 credit 用 ALERT 吐出來的是什麼內容.



58
#include <iostream>
#include <limits>
#include <map>
using std::cout;
using std::endl;
using std::map;

class Room_Data
{
      public:
             Room_Data() {cout<<"Construct"<<endl;}
             ~Room_Data() {cout<<"Destruct"<<endl;}
             char*        name;
             int          vnum;
};

int main()
{
    Room_Data *pRoom;
    pRoom = new Room_Data;
    pRoom->vnum = 2400;
   
    map<int, Room_Data> rMap;
    map<int, Room_Data>::reverse_iterator iter;
   
    rMap[pRoom->vnum] = *pRoom;
   
    for ( iter = rMap.rbegin() ; iter != rMap.rend(); iter++ )
    {
        cout<<iter->second.vnum<<endl;
        }
    cout<<pRoom->vnum<<endl;
    cout << "Press ENTER to quit." << std::flush;
    std::cin.ignore( std::numeric_limits <std::streamsize> ::max(), '\n' );
    return 0;
}


實驗一下..... 這麼好用 >_<" 不知在異步 IO 下 可不可以拿來做切換器......



59
IE8 會先載入 ELEMENT 才可以 在 JS 上 認的出 你指定的 OBJECT ID

很王八蛋的設計. ( SORRY 我是超級排軟派 )

解法 :

1. 在 MINE TYPE 上 下 :
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

2. 直接把 JS 放在 ELEMENT 下面

<BODY>

ELEMENT .......


JS : GET Object id.

</BODY>

感謝回複

第一個方法我加了還是沒有用

第二個方法 ... 是說把

<script type='text/javascript'>
   function show_credit(obj){
      credit = document.getElementById('credit');
      if(obj.value == '信用卡'){
         credit.style.display = 'inline';
      }
      else{
         credit.style.display = 'none';
      }
   }
</script>

這邊改變位置嗎... 改了還是一樣

你有先讓 ELEMENT 上的 ID 被讀取再去 叫 OBJECT ID 嗎?


60
講個笑話~~

很多年以前~剛失戀...

有個客戶一直PUSH 我去追他們配合的微軟女業務.

那個業務天天往他們公司跑. 而且聽說很正點~~~

當時我一直沒有動作.

@@" 因為我討厭微軟~~~


有冷到~~哈哈~~


頁: 1 [2] 3 4 ... 24