Windows system >> Windowsの知識 >  >> Linuxシステムチュートリアル >> Linuxチュートリアル >> 私はstraceのコマンドは、サーバー・プロセスをトレース使用今朝

私はstraceのコマンドは、サーバー・プロセスをトレース使用今朝

  

を検討するのLinuxサーバーのタイマー処理問題、定期点検サーバーは、複数のサーバプロセスがあることがわかったデッドロック状態に登場し、gdbがフォローアップしていき、下に示します:/lib/libc.so.6#3 0x00464df4から_L_lock_14080()で/lib/libc.so.6#2 0x00465b38から__lll_mutex_lock_wait()で
GDB)BT#0 __kernel_vsyscallで0x00ff9410()#1 0x004d593eでstd :: _ List_node< TTimeEvent>>オペレータに/lib/libc.so.6#4 0x006c7691 __gnu_cxx :: new_allocator<に/usr/lib/libstdc++.so.6#5 0x08059cfbから()を削除してからフリー(): :/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/extで割当て解除(これ= 0x98e0064、__P = 0x98e1218) STDにおける/new_allocator.h:94#6 0x08059d20 :: _リスト・ベース(LIST_BASE)< TTimeEvent、STD ::アロケータ< TTimeEvent>> :: _ M_put_node(この= 0x98e0064、__P = 0x98e1218)は/usr /libに/GCC /I386-redhat-でリナックス/C ++ /4.1.1 /ビット/stl_list.h含む/../../../..//4.1.1:320#STD 7 0x08059d81 ::リスト<を、TTimeEvent、STD ::アロケータ< TTimeEven T>> :: _ /usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../でM_erase(これは0x98e0064、__position = = {_ M_node = 0x98e1218}) /C ++ /4.1.1 /ビット/stl_list.hを含む:1150#STD 8 0x08059db3 ::リスト< TTimeEvent、STD ::アロケータ< TTimeEvent>> :: pop_front(これは0x98e0064 =)をUSR /LIB /GCC /AT CTimerManagerで/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/bits/stl_list.h:747#9 0x08059334 ::プロセス(この= 0x98e0058 )SRC /timermanager.cppで:SRC /timermanager.cppの処理で168#10 0x080597dd(nSigNo = 14):199#11<シグナルハンドラと呼ば> /lib/libc.soをより_int_free()における#12 0x004612ba。 6オペレータに/lib/libc.so.6#14 0x006c7691から遊離位13 0x00464e00()を削除()STDにおける/usr/lib/libstdc++.so.6#15 0x006a424dから::文字列:: _担当:: _ M_destroy ()から/usr/lib/libstdc++.so.6#16 0x0069e40fでSTD :: basic_stringbuf<チャー、STD :: char_traits<チャー> STD ::アロケータ<チャー>> ::〜basic_stringbuf()/USRから/lib/libstdc++.so.6#17 0x0069fd7fでSTD :: basic_stringstream<チャー、STD :: char_tr AITS<チャー> STD ::アロケータ<チャー>> /usr/lib/libstdc++.so.6#18 0x080524eaからCDBMoudle ::挿入に::〜basic_stringstream()(これ= tFixkey = @、0x98e6e80 0xbfe1c6ec)でSRC /dbmoudle.cpp:59#SRC /connectiontask.cppでCConnectionTask 19 0x08051718 :: ProcFixContent(これは0x98e6510を=):SRC /connectiontask.cppでCConnectionTask :: HandleRead 218#20 0x0805196e(これは0x98e6510を=):86# CConnectionTask 21 0x08051a0f ::ハンドル(この= 0x98e6510、nEvent = 1)SRC /connectiontask.cppに:主に133#23 0x08055328:iServer ::実行中の52#22 0x080585af SRC /server.cppで(これは0xbfe1c7e0 =) (のargc = 2、ARGV = 0xbfe1c8b4)のsrc /main.cppに時:19

#13で、自由を呼び出し、その後、libcの関数に関連して呼び出しますが、通話が終了していない前に。このプロセスでタイマー管理モジュール割り込み、プロセスの一部にタイマーは、また、無料の関数と呼ばれているので、デッドロック状態があります - 関数のmalloc関数/自由な家族がリエントラント、そこではないので、関連記事。私が代わって私のサーバーで試してみましたオブジェクトのコンストラクタ/デストラクタを最小化するためのコードが、一瞬思ったが、この戦略は、私は常に、コードを書くときに、デッドロックが今日で発生する可能性があり注意しなければならないことを意味する、ラジカルソリューションではありません明日はBであってもよく、 ..アイデアを変更することで、ローカルオブジェクトの構築と破棄のいくつかは、この問題を解決するために、その避けられない、C ++を使用しているので、でまた表示されます:現在のタイマ処理操作を簡素化しようと、私は戦略を考えますタイマーがトリガされたときと、代わりのトリガ時に適切なハンドラを呼び出すと、フラグを設定し、サイクルがメインサーバに設定されているかどうかを判断し、そう関連する場合には、再度処理を呼び出します機能したがって、オリジナルのアイデアは、次のとおり
//この関数はタイマーが起動されたときときにボイド信号(){//タイマーハンドラのdoSomething();}(1){サーバメインループしながら、考え後}

変更:
INTが違反g_alarm = 0; //タイマーがトリガされ、この関数場合ボイド信号g_alarm(){= 1;}一方、(1){サーバメインループ; IF(g_alarm){//タイマー処理番号doSomethingの(); g_alarm = 0;}}

これは、これは<補足誰歓迎するより良い方法がある場合、私は、現時点で考えることができ、この問題に対処するための最良の方法ですおそらくトップモデルチェンジです。 BR>

Copyright © Windowsの知識 All Rights Reserved