Home > Google OSS Archive
Google OSS Archive
gflags + glogでdeadlock? (2)
- 2009-05-13 (Wed)
- Google OSS

どうもgflagsからglogのMutexが呼ばれるのは何かおかしいと思っていたのだが、readelfで確認したところ、シンボルが競合しているようだ。
ソースコードからは競合しても問題無いようにコーディングしたいという意図が見えるが、glogからgflagsのMutexを使用しても問題が起こらないが、gflagsからglogのMutexを使用した場合に問題が起こるようだ。
id:nobu-q先生による解決策はこうですが、adhoc臭が漂いまくり(笑)
--- glog-0.2.1-orig/src/base/mutex.h 2009-01-22 07:17:01.000000000 +0900
+++ glog-0.2.1/src/base/mutex.h 2009-05-13 21:34:36.000000000 +0900
@@ -99,6 +99,8 @@
# error Need to implement mutex.h for your architecture, or #define NO_THREADS
#endif
+namespace hoge {
+
class Mutex {
public:
// Create a Mutex that is not held by anybody. This constructor is
@@ -246,9 +248,13 @@
void operator=(const WriterMutexLock&);
};
+};
+using namespace hoge;
でも本質的に解決するためには名前空間作るしか無いと思うのですがいかがでしょう? > shinhせんせい
googleのコードは必ず名前空間を作る雰囲気がしてたんですが、Mutexだけそうなってるのは歴史的事情かなんかなのかな。usingが禁止されてて面倒くさいのとstatic linkを使用しているので、よく使うものだけは例外的にglobalに有ったりするんだろうか。
- Comments: 0
- Trackbacks: 0
gflags + glogでdeadlock?
- 2009-05-13 (Wed)
- Google OSS

gflagsとglogの組み合わせだと、初期化時にデッドロックするケースが有る模様 @ RHEL5。ソースコードは以下のような感じ。
#include <glog/logging.h>
#include <google/gflags.h>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
google::InitGoogleLogging(argv[0]);
google::InstallFailureSignalHandler();
google::ParseCommandLineFlags(&argc, &argv, true);
cout << "hogehoge" << endl;
}
リンクの順番によって、デッドロックしたりしなかったり。
$ g++ test.cpp -lgflags -lglog; ./a.out hogehoge $ g++ test.cpp -lglog -lgflags; ./a.out ^C # deadlock occurs
gdbするとこんな感じ。
(gdb) bt #0 0x007c8402 in __kernel_vsyscall () #1 0x00787ceb in pthread_rwlock_wrlock () from /lib/libpthread.so.0 #2 0x00aaed87 in Mutex::Lock () from /opt/sedue/lib/libglog.so.0 #3 0x00aaedc3 in MutexLock::MutexLock () from /opt/sedue/lib/libglog.so.0 #4 0x00bb9034 in google::(anonymous namespace)::FlagRegistry::GlobalRegistry () from /opt/sedue/lib/libgflags.so.0 #5 0x00bbff49 in google::ParseCommandLineFlagsInternal () from /opt/sedue/lib/libgflags.so.0 #6 0x00bc0196 in google::ParseCommandLineFlags () from /opt/sedue/lib/libgflags.so.0 #7 0x080488a3 in main ()
-g付き。
(gdb) bt #0 0x003fe402 in __kernel_vsyscall () #1 0x002d4ceb in pthread_rwlock_wrlock () from /lib/libpthread.so.0 #2 0x00ca0d87 in Mutex::Lock (this=0x44e904) at src/base/mutex.h:171 #3 0x00ca0dc3 in MutexLock (this=0xbfa390cc, mu=0x44e904) at src/base/mutex.h:217 #4 0x00435034 in GlobalRegistry () at src/gflags.cc:675 #5 0x0043bf49 in ParseCommandLineFlagsInternal (argc=0xbfa391d4, argv=0xbfa391d0, remove_flags=true, do_report=true) at src/gflags.cc:1825 #6 0x0043c196 in google::ParseCommandLineFlags (argc=0xbfa391d4, argv=0xbfa391d0, remove_flags=true) at src/gflags.cc:1855 #7 0x0804d9b3 in main (argc=1, argv=Cannot access memory at address 0x84 ) at hoge.cpp:111
初期化順序に問題が有る気がするんだけど、ちょっとソース見た感じでは分からなかったので、バグ報告的エントリ。
- Comments: 7
- Trackbacks: 0
Googleのロギングライブラリgoogle-glogを使ってみる
- 2008-10-15 (Wed)
- Google OSS

“google glog”で探せないgoogle-glogを軽く使ってみました。Googleからオープンソースで公開されたC++向けのロギングライブラリです。以下のエントリが参考になります。
google-gflags 1.0と、google-glog 0.1をダウンロードしてインストールします。今回はgoogle-gflagsを使用する場合についてのみ記述します。また、glogのマニュアルに一通り目を通してから読まれると良いかと思います。
まずはとにかく動かしてみます。
#include
int
main(int argc, char **argv)
{
google::InitGoogleLogging(argv[0]);
google::ParseCommandLineFlags(&argc, &argv, true);
LOG(INFO) << "INFO";
LOG(WARNING) << "WARNING";
LOG(ERROR) << "ERROR";
LOG(FATAL) << "FATAL";
}
これをコンパイル & 実行。
pficore% g++ glog.cpp -lglog -lpthread -lgflags; ./a.out E1015 131626 glog.cpp:9] ERROR F1015 131626 glog.cpp:10] FATAL @ 0x2abe222d5ca7 google::LogMessage::SendToLog() @ 0x2abe222d2017 google::LogMessage::Flush() @ 0x2abe222d2216 google::LogMessageFatal::~LogMessageFatal() @ 0x400bb8 main @ 0x2abe230d68e4 (unknown) @ 0x4009c9 (unknown)
デフォルトではERROR以上のレベルが標準出力に吐かれます。また、FATALを吐くと自動的にバックトレースを出力してくれます。
次はファイルに書き出してみます。これには-log_dirオプションを指定します(オプション一覧は./a.out –helpで見ることができます)。
pficore% ./a.out -log_dir=. E1015 131953 glog.cpp:9] ERROR F1015 131953 glog.cpp:10] FATAL @ 0x2b685d158ca7 google::LogMessage::SendToLog() @ 0x2b685d155017 google::LogMessage::Flush() @ 0x2b685d155216 google::LogMessageFatal::~LogMessageFatal() @ 0x400bb8 main @ 0x2b685df598e4 (unknown) @ 0x4009c9 (unknown) pficore% ls a.out a.out.INFO a.out.pficore.dyndns.org.kzk.log.FATAL.20081015-131953.7491 glog.cpp a.out.ERROR a.out.WARNING a.out.pficore.dyndns.org.kzk.log.INFO.20081015-131953.7491 a.out.FATAL a.out.pficore.dyndns.org.kzk.log.ERROR.20081015-131953.7491 a.out.pficore.dyndns.org.kzk.log.WARNING.20081015-131953.7491
ログファイル名は、”program name”.”hostname”.”user name”.log.”severity level”.”date”.”time”.”pid”になります。また、-log_dirオプションを指定しない場合は実は/tmpに吐かれています。また、”program name”.”serverity level”という名前で最新の実行結果のログへのリンクが作成されます。
デバッグ用にstderrだけにログファイルを吐きたい場合は、-logtostderr=1というフラグをつけます。標準ではERRORレベル以上のものしか出力されないので、-stderrthreshold=0とするとINFOから出力されます (ログレベルはINFO, WARNING, ERROR, FATAL の順に 0, 1, 2, 3)。
pficore% ./a.out -logtostderr=1 -stderrthreshold=0 I1015 133604 glog.cpp:7] INFO W1015 133604 glog.cpp:8] WARNING E1015 133604 glog.cpp:9] ERROR F1015 133604 glog.cpp:10] FATAL @ 0x2ba7fa406ca7 google::LogMessage::SendToLog() @ 0x2ba7fa403017 google::LogMessage::Flush() @ 0x2ba7fa403216 google::LogMessageFatal::~LogMessageFatal() @ 0x400bb8 main @ 0x2ba7fb2078e4 (unknown) @ 0x4009c9 (unknown)
ファイルにもstderrにも吐かせたい場合は、-alsologtostderr=1というフラグを利用します。
デバッグ時にはVLOG関数が役立ちます。
#include
int
main(int argc, char **argv)
{
google::InitGoogleLogging(argv[0]);
google::ParseCommandLineFlags(&amp;amp;amp;amp;amp;amp;amp;argc, &amp;amp;amp;amp;amp;amp;amp;argv, true);
VLOG(1) << "VLOG 1";
VLOG(2) << "VLOG 2";
}
コンパイル & 実行します。
pficore% g++ glog.cpp -lglog -lpthread -lgflags; pficore% ./a.out -v=1 -logtostderr=1 -stderrthreshold=0 I1015 134214 glog.cpp:7] VLOG 1 pficore% ./a.out -v=2 -logtostderr=1 -stderrthreshold=0 I1015 134218 glog.cpp:7] VLOG 1 I1015 134218 glog.cpp:8] VLOG 2
VLOGのレベルはINFOと同じなので、-stderrthreshold=0を指定しています。また、-v=Nと指定すると、VLOG(X) (ただし X <= N) のメッセージが表示されます。
後、まだ動かし方が分かってないのが、moduleです。ファイル名ベースでモジュールが作成されるようなのですが、以下のようにしても何も出ないので、もう少し調べる必要が有りそうです (suffixは.ccに変更)。凄く初歩的なミスをしている気がしてならない。
#include
int
main(int argc, char **argv)
{
google::InitGoogleLogging(argv[0]);
google::ParseCommandLineFlags(&amp;amp;amp;amp;amp;amp;amp;argc, &amp;amp;amp;amp;amp;amp;amp;argv, true);
VLOG(1) << "VLOG 1";
VLOG(2) << "VLOG 2";
}
pficore% g++ glog.cc -lglog -lpthread -lgflags
pficore% ./a.out --vmodule=glog=2 -logtostderr=1 -stderrthreshold=0
一定レベル以上のメッセージをメールで送信する機能もあるので、これも試してみたいと思っています。ログローテート周りも調べないとな。ざっとそんな感じです。
ちょうどid:tkngさんと、ロギングライブラリ欲しいよねーと話していたところにこれがリリースされたので、正直凄くありがたいです。欲しい機能は大体あるし。
google++ shinh++ !!!
P.S
このコメントへーって思った。
// fwrite() doesn't return an error when the disk is full, for // messages that are less than 4096 bytes. When the disk is full, // it returns the message length for messages that are less than // 4096 bytes. fwrite() returns 4096 for message lengths that are // greater than 4096, thereby indicating an error.
まあfwrite()の返り値は write(2)で泣きを見た ISer なら誰でもチェックすると思われるが (including me)、disk full時の細かい挙動までは知らなかった。
- Comments: 0
- Trackbacks: 0
「プロトコルバッファー」がオープンソース化
- 2008-07-08 (Tue)
- Google OSS

Googleで使用されているRPC/シリアライズフレームワーク「ProtocolBuffer」がオープンソース化されたらしい via @ohkuraさん
おーおーお、GoogleTestといい何かオープンソース化ラッシュですね。FacebookのThriftと比較してC++, Java, Pythonしかバインディングが無いので、PHPとかPerlとか使ってる場合はまだ移行できなさそう。
この2つは週末に時間とってじっくり調べてみようー。
追記:
RPCの部分は無くて、シリアライズのところしかなかった・・・。
追記:
RPC有るっぽ。
- Comments: 0
- Trackbacks: 0
お
- 2007-12-19 (Wed)
- Google OSS

今更ながらyupo先生もgoogle perf toolsについて書かれているのを発見。はてブ万歳。LDR見落としたっぽいな・・・。
- Comments: 0
- Trackbacks: 0
Home > Google OSS Archive
-
- August 2010
- May 2010
- February 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
