C++

構造体のサイズ違いで悩んだのでリンク時に検出

先日、次のようなC++のクラスが原因で少々悩みました。 struct A { #ifdef V2 int bar_; /* バージョン2以降でしか使わないメンバ変数(らしい) */ #endif int foo_; /* 以下略 */ }; このAを使っている.cppの一部は、g++ -DV2でコンパイルされており、残りは…

関数テンプレートの特殊化について

C++

関数テンプレートの特殊化いろいろ なんか日記を書くのを忘れていました。よくない。というわけで、最近おぼえたtipsを書きます。クラステンプレート内のテンプレートの特殊化(もどき)についての自分なりのまとめ。 まず、 namespace A { template<int V> static </int>…

Java の ConTest っぽいものを、glibcの新機能(LD_AUDIT)を使って Linux + C/C++ で実現してみる

たまには何か書きます。C/C++のマルチスレッドなプログラムのユニットテストでバグを効率的に見つけるためのライブラリ?の作成について。 IBM dWのConTest はてなブックマークを眺めていたら、「ConTestを使用したマルチスレッド・ユニットのテスト - 並列テ…

GCCの-ftrapv (3)

さて、インフルエンザで寝込んでいる最中ですがここぞとばかりに更新。 以前書いたGCCの-ftrapvをそろそろ実戦投入するかと思ったんですが、3つほど注意点を見つけたのでメモ。 問題1: 3.3.x以前でちゃんとうごかない GCC 3.3.x 以前のlibgccの実装にはバグ…

シグナルハンドラを使わないでシグナルをハンドルする

「シグナルハンドラの中でできることは非常に限られているんですよ」というお話を1年半くらい前に書きましたが、この話には続きがあって、ある特定の条件下ではこの制限を緩和することができます。今回はその方法についての解説です。sigwait(3)という関数を…

GCCの-ftrapv (2)

前回、GCCの-ftrapvを使用すると、符号あり整数同士の演算におけるオーバーフローを検出し、オーバーフロー時にabort()が呼ばれることを示しました。しかし、「abortじゃ意味ないんだよねー、C++の例外をthrowするとか、せめてbacktraceを表示するとかしてく…

「C++と組み込み環境」

C++

というblogを見つけました。こちらです。組み込みと銘打っていますが、C開発者向けにC++のpitfallを解説した記事として大変に有益と思います。C++規格の章番号を出して解説してくれているのは大変goodですね。 個人的には9月の記事、8月の記事がツボ。

signed intでの配列アクセスはマジヤバイ(こともある)

C++

次のC/C++なコードには問題があります。 #define A_SIZE 6 static int a[A_SIZE]; void vuln(int n, int val) { assert(n < A_SIZE); a[n] = val; }配列アクセスの添字となる変数aの方が signed int なのが問題です。nとして負数を渡すと面白い(というか恐…

integer overflow 流行りな昨今 (3)

現実的な解決策 in C++ でも、クイズに書いたようなオーバーフローって、なかなか防ぎきれないんですよね。 技術力を向上する がんばってレビューする 静的なコード検査ツールを使う(QAC++とか、PolySpaceとか、これとか) などが王道かとは思いますが、学習…

GCC-4.1.0 and ProPolice/SH

えとーさんに教えてもらって参加した SEA & FSIJ 合同フォーラム2005年12月 「GCC行く年来る年」で伺ったところによると、GCCの4.1でIBM東京基礎研のProPoliceがマージされて、しかもx86だけでなく、x86_64, ppc, sparc, s390, そしてshがサポートされるそう…

operator newの隠れた整数オーバーフローとVisualStudio 2005のVC++

C++

void vuln(std::size_t nelem) { int* p = new int[nelem]; std::memset(p, 12345, nelem); }上記の関数には整数オーバーフローに起因するヒープベースバッファオーバーフローの脆弱性があるんですが、どこがまずいかわかりますか? まずいのはnewしている部…

GCCの-ftrapv

gcc -ftrapv 最近のGCC(>=3.x)には-ftrapvというオプションがあって、これを有効にすると「符号あり整数同士の加算・減算・乗算でオーバーフロー/アンダーフローが発生したとき、プロセスをabort()」してくれます。例えば、INT_MAX + 1 とか INT_MIN - 1 と…

g++ の -fthreadsafe-statics ってオプション知ってます?

C++

古来より、関数スコープの静的なオブジェクトを作るのは危険 void foo() { static CBar bar; // こんなの とされています。foo()が初めて呼ばれたタイミングでbarのコンストラクタが走るわけですが(C++規格でそう決まっている)、foo()の初回呼び出しが2つの…

C++例外がCのコード中を通過するとクラッシュする件

C++

woさんに教えていただいた件 (http://d.hatena.ne.jp/w_o/20051203#p3)、遅くなりましたが、現象確認しました。次のコードで再現しますね。 $ cat a.cpp extern "C" { void b(); void a() { throw 123; } } int main() { try { b(); } catch(...) {} } $ cat…

Singleton速度比較 (4) 感想

C++

500,000,000回まわしてこの程度の処理時間ですから、どれも高速だと思う。差なんてないようなものではなかろうか。むしろ、Singleton(=グローバル変数)なんて殆ど使わなくて済むような設計を心がけるべきで、完全同期バージョンのSingletonを使ってパフォー…

Singleton速度比較 (3) ソースコード

C++

(1) SynchronizedSingleton: 完全同期型Singleton 特に説明は不要でしょう。non-PODでstaticなオブジェクトを使用するのは好きじゃありませんが(メンバ変数m)、今回は目を瞑ります。 template<typename T> class SynchronizedSingleton : private boost::noncopyable { p</typename>…

Singleton速度比較 (2) 結果

C++

結果は次の通り。 $ ./a.out DCLSingleton: 0.27 [s] GccTSDSingleton: 0.62 [s] OnceSingleton: 17.08 [s] TSDSingleton: 22.83 [s] SynchronizedSingleton: 52.95 [s] 手法処理時間(1/Sync比)処理時間(DCL比) DCLSingleton196.11.0 GccTSDSingleton85.42.3…

Singleton速度比較 (1)

C++

2chのマルチスレッドスレッドで興味深い議論があった。見ていただければわかるが、「C++でdouble checked locking(DCL)は安全か」という話題を、CPU毎に検討している。各CPUのmemory modelの話に立ち入った、楽しい議論だ。特に、リンクされている Double-Ch…

標準に非準拠の実害

IRCでちょっと突っ込み貰ったので補足。 ぼくが「〜しないほうがいいよ」と書いた処理、たとえば「シグナルハンドラで様々な処理を行う」などしているソースコードって、オープンソースのものも含めて結構あると思いますけど、大部分ちゃんと動いています。…

シグナルハンドラからのforkするのは安全か? (2) シングルスレッドの場合 - サンプルコード

シングルスレッドのコードでシグナルハンドラ中でforkし、子プロセスが非同期シグナルセーフな関数を呼んでデッドロックする実例です。 非同期シグナルセーフな関数として a() を用意しました。この関数は入り口でmutexをロック、中で10秒寝て、mutexをアン…

シグナルハンドラからのforkするのは安全か? (2) シングルスレッドの場合

シングルスレッドの場合、シグナルハンドラからforkする場合には次のどちらかの方法を取れば安全です(どちらも子プロセスの話)。 fork直後に(printfを含む如何なる関数も呼ばずに)すぐにexecする execしない場合、子プロセスは自身が消滅(exit)するまで「非…

シグナルハンドラからのforkするのは安全か? (1) マルチスレッドの場合

マルチスレッドのプログラムが、(シグナルハンドラ以外から)forkするときに注意事項があることは既に書きましたが、「forkをシグナルハンドラの中から行いたい」というケースでは、さらに追加の注意事項があります。 一般に、シグナルハンドラでforkしてよい…

localtimeやstrtokは本当にスレッドセーフにできないのか (3): GCC __thread keyword

C++

3.3以降のgccを使っているのであれば、pthread_getspecific関数を使うのと同様のことを、特殊なキーワード __thread を使って実現できます。上で示したlocaltime関数の、長ったらしいソースコードは、次のように簡潔に書き直せます。 #include <time.h> #include <stdlib.h> st</stdlib.h></time.h>…

localtimeやstrtokは本当にスレッドセーフにできないのか (2)

C++

localtime関数は、返却するデータを、スレッド固有データ(Thread Specific Data, 略して TSD*1 )として確保すれば、スレッドセーフな関数として実装できると思います。 グローバル変数や、関数内で宣言されたstatic変数など、「静的な記憶期間をもつ変数」は…

localtimeやstrtokは本当にスレッドセーフにできないのか (1)

C++

googleから私の日記に、localtime_r や strtok_r, getpwnam_r などのキーワードで飛んでくる方が結構多いので、ちょっと関連する話題を書いてみます(内容の割に長い…)。 さて、8/9の日記で、POSIXのlocaltimeという関数(下記)を取り上げ、 struct tm *localt…

GCCの警告(implicit narrowing conversion)

2ちゃんねる GCCスレより。 116 名前:デフォルトの名無しさん 投稿日:04/08/30 11:43 long longの変数をint型の変数に代入した時、警告するようなオプションってありますでしょうか? integer overflow を起こしていそうな場所の目星をつけるのに、確かに…

TSF一覧

"[C++] UNIX上でのC++ソフトウェア設計の定石 (6)"で、"SUSv3に、TSF(Thread Safe Function) の一覧はないと思う" と書きましたが、ありますね。 正式な規格ではなくRationaleとしてですが、XSI Supported Functionsのところに、 On XSI-conformant systems,…

UNIX上でのC++ソフトウェア設計の定石 (6) -- おまけ

C++

スレッドセーフな関数を、 局所的静的変数(関数内のstatic変数)や非局所的静的変数(大域変数)の操作をしない。かつ、他の非スレッドセーフな関数を呼んでいない そういう変数の操作をするが、その部分をmutexなどで同期化し、複数のスレッドが同時に操作しな…

UNIX上でのC++ソフトウェア設計の定石 (6) -- 続き

C++

鉄則6: マルチスレッドプログラミングの「常識」を守ろう POSIXの標準関数のうち、非スレッドセーフであるものの一覧を把握し、使わないようにせよ 自作の関数はスレッドセーフにせよ 共有変数はロックして参照・更新せよ C++を使っているなら、関数を同期化…

UNIX上でのC++ソフトウェア設計の定石 (6)

C++

鉄則6: マルチスレッドプログラミングの「常識」を守ろう POSIXの標準関数のうち、非スレッドセーフであるものの一覧を把握し、使わないようにせよ 自作の関数はスレッドセーフにせよ 共有変数はロックして参照・更新せよ C++を使っているなら、関数を同期化…