謎のシンボル (C++)

某コンパイラで某ソースをコンパイルしたら、こんなシンボルが生成された。

Undefined symbols:
  "_id__Q2_3std31codecvt__tm__16_cc11__mbstate_t", referenced from:

で、これがリンク時に未解決でコケる。

C++ なので、コンパイルするときに名前がなが〜くなって非常に判りにくかったが、 codecvt という部分で STL のストリームっぽいことが判る。当然のように当該ソース中には、こんなものを明示的に使ってる部分はなくって、いよいよ判りにくい。

で、なんでリンクできなくてこけるかというと、いちおうそれっぽいシンボルはライブラリの中で define されている。

: nm libstd.a|grep codecvt__tm__|grep _id   
nm: no name list
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_wc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_wc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_wc9mbstate_t
0000000000018c30 D _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
0000000000018c40 D _id__Q2_3std28codecvt__tm__13_wc9mbstate_t

問題となっているソースの方(実はとあるライブラリ)はこう

: nm libplatform.a |grep codecvt__tm__|grep _id 
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std31codecvt__tm__16_cc11__mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t
                 U _id__Q2_3std28codecvt__tm__13_cc9mbstate_t

・・・・・なんでか、1個だけ微妙にシンボル名が違いますが!

というのがヒントになって何となく判った。問題となるソースをコンパイルしたときだけ怪しいシンボル名になって埋まるが、その他のソースでは正常な名前でオブジェクトコードができてる。しかし、こんなクラス明示的にはどっちでも使ってないんだがな・・・ってことで cpp 通した後で比較してみる。

非常に判りにくかったが、やっと判った違いはこれ。 i386/_types.h の中で定義されているのだが、 cpp を通ってみると

駄目だった方

  1.  

正しい方

  1.  

理由は判らないが、アンスコ二つがとれないのが駄目なようだ。なにがそういう操作しているのかまで追っかける気力がなかったので、二つのソースでヘッダのインクルード順見て、適当に iostream を先頭でインクルードしてやったらちゃんとリンクできるようになったので解決したことにする。

どうでもいいけど、gcc の cpp の -x オプション、ちゃんと解釈できなくなってない?なんでか cpp-4.0 なんてのも入っていて、そっちはちゃんと動いたからいいけど。 C++ のソースなんだから iostream とかちゃんと include できてくれっつーの。

これも関係ないが、無駄に全力で最適化なんかやっているので、最後のリンクはこんなにしんどい。いやちゃんとリンク不可能なシンボルが生成していないか先に確認すればいいんだけど。

Processes:  64 total, 3 running, 61 sleeping... 219 threads             16:13:47
Load Avg:  1.02,  0.89,  0.83    CPU usage:  7.73% user, 20.91% sys, 71.36% idle
SharedLibs: num =    7, resident =   16M code,  196K data, 1196K linkedit.
MemRegions: num = 23227, resident = 1765M + 4972K private,   25M shared.
PhysMem:  226M wired, 1204M active,  595M inactive, 2033M used,   15M free.
VM: 11G + 371M   19277151(1340) pageins, 8280949(81) pageouts

  PID COMMAND      %CPU   TIME   #TH #PRTS #MREGS RPRVT  RSHRD  RSIZE  VSIZE
56053 pgipa       29.4% 15:23.85   1    13  13656 1701M-  184K  1687M- 4024M 
53466 pmTool       9.2%  4:50.30   1    24     38  824K   356K  2136K    29M 
56112 top          8.5%  0:00.76   1    18     33  524K   228K  1128K    18M 
    0 kernel_tas   4.3%  4:50:08  58     2   1398 5992K+     0   135M+  351M+
53465 Activity M   3.1%  4:31.64   5   113    299 6032K  7220K    11M+  415M 
53444 Terminal     1.2%  1:25.58   3   107    254   20M+ 5028K    26M+  383M 

実メモリ 2G の計算機で 6G くらいのプロセスになっちゃって、 swaping ばっかで全然終わらない・・・・。2時間くらいかけてプロセスタイム20分とか。


15:26:00 - 04.10.08 - kuroyagi - その他雑記 - 3800x