注册账号 登录
小春网 返回首页

崖上のオッサン的个人空间 https://www.incnjp.com/?192660 [收藏] [复制] [分享] [RSS]

日志

泥沼に向かって全力で走りだす前に

已有 1056 次阅读2014-1-6 15:39 |系统分类:闲谈

今回も適度になんかしゃべろう~  _(:3 」∠ )_ゴロンゴロン

■今回のデーマはGDBでw
システムやgdbを疑い出したら死亡フラグ。そんなことは絶対にない!
ディスアセンブルしたり、カーネルのソース追いかけたり、サンプルソース作ったり…手段を駆使する前に以下を読め!
●一度冷静になってから、全ての手順を再確認せよ。 ←一番大事!これによっては以下の確認も不要かも・・
●gdbの挙動がおかしい?
そのバイナリとgdb繋いでるプロセスは本当に同一か?make install忘れてないか?
リンクだったり、コピーだったり。別のディレクトリだったり、対向マシンの同じディレクトリだったり。
稼働中プロセスに別のmapをあてはめてデバッガ起動したら、そりゃおかしいわな。
ソース更新したのに挙動が変わらなければ、いつもの俺なら、ちゃんと疑うよね?w
●straceで何も出なくておかしい?
落ち着け。マルチスレッドならオプション要るよね。 ←よくこういう風に自分に問いかけてるので無視~w
⇒ついでに fork追跡に関して、、
  set follow-fork-mode <parent|child|ask>
parentは親を、childは子をデバッグする。askはどっちにするか聞いてくれる。
指定した方にはブレイクが残る。他方はブレイク解除される。
●STLの挙動がおかしい?
ロックとらずにSTL持ってるオブジェクトをコピーしてないか?引数渡しでの暗黙のコピーとか。
やはり当たり前の話ばかりだよね(◍′ω‵◍;)
うんじゃ、下ネタはこの辺にして、別物を見てみよう~

■boost::anyの見方 ←なんでも格納できるクラスで意外と使えるw
先に結論を言うと、p (対象の型)*(対象のcontent + 1) で表示できる。
string型を格納したboost::any infoなら、p (string)*(info.content + 1)となる。

確認用サンプルソース
 boost::any dataArray[26];
 std::string str_data[] =    {"aa", ... };
 dataArray[0] = str_data[0];
この行を実行した後、dataArray[0]に"aa"がちゃんと入っているか確認してみよう~

(gdb) p dataArray[0]
$1 = {content = 0x8c170c0}      #contentというメンバがあるんだな
(gdb) p dataArray[0].content      #そのcontentを表示してみる
$2 = (class boost::any::placeholder *) 0x8c170c0
(gdb) p *dataArray[0].content     #アドレスらしいから*付けてみる
warning: RTTI symbol not found for class 'boost::any::holder<std::string>'
$3 = {_vptr.placeholder = 0x805aef8}  #めげそう…だが先頭が仮想関数テーブルであることは分かる。
(gdb) ptype dataArray[0]         #とりあえず型を調べることにする。
type = class boost::any {
  private:
    class boost::any::placeholder *content;
    (以下略)
(gdb) ptype *dataArray[0].content  #*contentも型を調べてみる
type = class boost::any::placeholder {
  public:
    ~placeholder(int);
    virtual const struct std::type_info & type() const;
    virtual class boost::any::placeholder * clone() const;
}

やはり仮想関数がある。ってことは先頭1ワードは仮想関数テーブルだから実体は次のアドレスに格納されている。たぶん。
+1(ポインタだから実際には4バイト加算)したアドレスをstringでキャストして表示してみる。

(gdb) p (string)*(dataArray[0].content + 1)
$6 = {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
   _M_p = 0x8c16e54 "aa"}}      #ビンゴ!あったぞ

ちなみに、コピーして代入したはずなのに、元データ(str_data[0])の実体と同じアドレスを指しているが、問題ない。
STLは効率化のため、値を書き換えない間は同じ実体を参照する仕組みだからね。

(gdb) p str_data[0]
$11 = {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
    _M_p = 0x8c16e54 "aa"}}      #コピーしたdataArray[0]の方と同じアドレス

(gdb) p (*rcv_msg.pimpl).apu_id.pimpl.m_serviceSupplierNumber 
There is no member or method named m_serviceSupplierNumber. 
(gdb) p/x (*(*rcv_msg.pimpl).apu_id.pimpl).m_serviceSupplierNumber 
$24 = 0x2c0000 (gdb) p/x (*(*rcv_msg.pimpl).apu_id.pimpl).binary 
$25 = {<std::_Vector_base<unsigned char,std::allocator<unsigned char> >> = 
{
  _M_impl = {<std::allocator<unsigned char>> = {<__gnu_cxx::new_allocator<unsigned char>> = {<No data fields>}, <No data fields>}, _M_start = 0x872b4c0, _M_finish = 0x872b4c8,
   _M_end_of_storage = 0x872b4c8}}, <No data fields>

(gdb) p msg->getCommonHeader().get_message_type() 
(gdb) p *msg->getCommonHeader().pimpl メソッドは呼べる。

(๑¯ω¯๑)終わり~

悲剧

无聊

震惊

支持

不解

超赞

愤怒

高兴

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册账号

小春网
常务客服微信
微信订阅号
手机客户端
扫一扫,查看更方便! 返回顶部