0

私たちのアプリケーションはtclそれに埋め込まれていて、starkit;を使用しています。tk静的にリンクされています。

アプリケーションを実行すると、起動guiしてすべてのキーに応答しますが、を押しctrl+dて終了するとハングします。投稿の最後にハングのバックトレースを示しました。

まずTcl/Tk、アプリケーションにどのように埋め込むかについて説明します。

#--------------------------------------------------------------
# (*) install ActiveTcl
# we need starkit and ActiveTcl tclsh is batteries included
#--------------------------------------------------------------
% tar -xzf ActiveTcl8.5.8.1.291945-linux-x86_64-threaded.tar.gz
% cd ActiveTcl8.5.8.1.291945-linux-x86_64-threaded
# specify /a/b/tcltk8.5.8/linux26_x86_64 as install dir in gui
% ./install.sh

アプリケーションをクラッシュtkさせていたので、TrueTypeフォントなしで必要です。ソースからインストールするには、コンパイルする必要があります:( Active-Tclディレクトリをポイントしてコンパイルする方法がわかりません。オプションがある場合はお知らせください)tktcltk--with-tcl

#--------------------------------------------------------------
# (*) install tcl from sources
#--------------------------------------------------------------
% tar -xzf tcl8.5.8-src.tar.gz 
% cd tcl8.5.8/unix
% ./configure --prefix=/a/b/tcltk8.5.8/linux26_x86_64 \
              --enable-shared=no \
              --enable-threads 
% gmake

ActiveTclのtclshを保持する必要があるgmake installため、これはできません。tcl次のインストールtk

#--------------------------------------------------------------
# (*) install tk from sources
# need to disable xft (true type font) set --disable-xft
#--------------------------------------------------------------
% tar -xzf tk8.5.8-src.tar.gz 
% cd tk8.5.8/unix
% ./configure --prefix=/a/b/tcltk8.5.8/linux26_x86_64 \
              --enable-shared=no \
              --with-tcl=/a/b/tcltk8.5.8/src/tcl8.5.8/unix \
              --disable-xft \ 
              --enable-threads
% gmake
% gmake install

今、私は以下を使用してアプリケーションを実行していますgdb

% gdb rs
% r -gui

ヒットctrl+dするとハングが発生し、次のバックトレースが得られます。誰かが私がこの問題を解決するのを手伝ってもらえますか?

Program received signal SIGINT, Interrupt.
[Switching to Thread 182897358720 (LWP 9535)]
0x0000003739608b3a in pthread_cond_wait@@GLIBC_2.3.2 ()
   from /lib64/tls/libpthread.so.0
(gdb) bt
#0  0x0000003739608b3a in pthread_cond_wait@@GLIBC_2.3.2 ()
   from /lib64/tls/libpthread.so.0
#1  0x0000000001833e22 in Tcl_ConditionWait ()
#2  0x0000000001834d41 in Tcl_WaitForEvent ()
#3  0x00000000017fec68 in Tcl_DoOneEvent ()
#4  0x00000000017cb4ad in Tcl_VwaitObjCmd ()
#5  0x000000000178b6ec in TclEvalObjvInternal ()
#6  0x00000000017cd08d in TclExecuteByteCode ()
#7  0x00000000017d5798 in TclCompEvalObj ()
#8  0x000000000178d6ac in TclEvalObjEx ()
#9  0x00000000017939c4 in Tcl_CatchObjCmd ()
#10 0x000000000178b6ec in TclEvalObjvInternal ()
#11 0x00000000017cd08d in TclExecuteByteCode ()
#12 0x00000000017d5a84 in Tcl_ExprObj ()
#13 0x000000000178c3e3 in Tcl_ExprBooleanObj ()
#14 0x0000000001796704 in Tcl_IfObjCmd ()
#15 0x000000000178b6ec in TclEvalObjvInternal ()
#16 0x000000000178cee6 in TclEvalEx ()
#17 0x000000000178d616 in Tcl_EvalEx ()
#18 0x00000000017f1be9 in Tcl_FSEvalFileEx ()
#19 0x000000000179c385 in Tcl_SourceObjCmd ()
#20 0x000000000178b6ec in TclEvalObjvInternal ()
#21 0x000000000178cee6 in TclEvalEx ()
---Type <return> to continue, or q <return> to quit---
#22 0x000000000178d616 in Tcl_EvalEx ()
#23 0x000000000178d9d8 in TclEvalObjEx ()
#24 0x000000000180d45f in Tcl_UplevelObjCmd ()
#25 0x000000000178b6ec in TclEvalObjvInternal ()
#26 0x00000000017cd08d in TclExecuteByteCode ()
#27 0x000000000180e4cd in TclObjInterpProcCore ()
#28 0x000000000178b6ec in TclEvalObjvInternal ()
#29 0x000000000178cee6 in TclEvalEx ()
#30 0x000000000178d616 in Tcl_EvalEx ()
#31 0x000000000178dacd in Tcl_Eval ()
#32 0x00000000008f26aa in xrAppPlatformInit (interp=0x211a410)
    at xrAppPlatform.c:430
#33 0x00000000017f69ca in Tcl_Main ()
#34 0x00000000008f2153 in xrMain (argc=3, argv=0x20fe880)
    at xrAppPlatform.c:177
#35 0x00000000008f1092 in main (argc=2, argv=0x7fbfffe718) at main.cpp:213
4

1 に答える 1

4

Ctrl+は、D端末によってEOFインジケータとして解釈されます。これは、stdinチャネル(Tclレベル)がEOF状態になることを意味します。問題は、コードがそれにどのように応答するかということです。そのようなことを完全にカスタマイズするためのTclコードを書くことができるので、そこで一般的なことを言うのは非常に難しいです。

ただし、(スタックトレースから)vwait使用中(つまり、カスタムイベントループ)であることがわかります。exitしたがって、問題は、コードがEOFに正しく反応しておらず、ループを使用しているか、ループを終了させて​​いないことだと思います。これを検出するには、そのチャネルから読み取ろうとする読み取り可能値を設定する必要があります(これまでのところ通常fileevent)。stdin読み取りに失敗した場合は、でEOFを確認し、eof適切なアクションを実行してください…</ p>

于 2012-05-19T08:09:52.697 に答える