GB | BIG5
|
| 首頁 > 編程技術 > C/C++ > 正文 |
 |
| Solaris2.4 多線程編程指南6--編譯和調試 |
| 本文出自:BBS水木清華站 作者:Mccartney (coolcat) (2002-01-29 20:32:52) |
6 編譯和調試 本章描述了怎樣編譯和調試多線程程序。 編譯一個多線程應用程序 調試一個多線程應用程序 6.1編譯一個多線程應用程序 6.1.1使用C編譯器 確認你擁有如下軟件,否則將無法正常編譯和連接多線程程序 ﹒ 頭文件:thread.h errno.h ﹒ 標準C編譯器 ﹒ 標準Solaris連接器 ﹒ 線程庫(libthread) ﹒ MT-Safe庫(libc, libm, libw, libintl, libmalloc, libmapmalloc, libnsl, 等等) 6.1.2用替代(_REENTRANT)標志進行編譯 在編譯多線程程序時使用"-D _REENTRANT"標志。 這個標志必須在編譯應用程序的每一個模塊時都使用。如果沒有這個標志,將使用errno, stdio等等的舊的定義。如果要編譯一個單線程應用程序,不要使用這個標志。 *新舊連接需要小心 表6-1顯示了多線程目標代碼模塊與舊的代碼模塊連接時需要非常慎重。 表6-1 在編譯多線程程序時使用"-D _REENTRANT"標志 文件類型 編譯 參考 返回 舊的目標文件(非線程版)和新的目標文件 沒有 "-D _REENTRANT" 標志。 靜態儲存 傳統的errno 新的目標文件 有 "-D _REENTRANT"標志。 __errno,新的二進制入口 線程定義errno的地址 用libnsl 裡的TLI編程 有 "-D _REENTRANT"標志(必須)。 __t_errno,一個新的入口 線程定義t_errno的地址 6.1.3使用libthread 為了在連接時使用libthread,需要在ld命令行裡,-lc參數之前,指定 -lthread,或者在cc 命令行的最指定。 如果應用程序沒有連接libthread,則對該庫中的函數調用不產生實際操作。 Libc定義libthread為空過程。???真正的過程是在應用程序既連接libc也 連接libthread時由libthread加入的。 如果一個ld命令行包含了以下的字段:.o's ... -lc -lthread ...,則C函數庫的行為沒有被定義。??? 不要在單線程程序中使用-lthread。這樣做將在連接時建立多線程機制,在運 行時將被初始化。這樣做不但浪費資源,而且在調試中會對運行結果有不正確的顯示。 6.1.4使用非C的編譯器 線程庫使用libc中的如下內容: ﹒ 系統調用包裝器(system call wrappers) ﹒ 用來顯示出錯信息的調用(通常是printf) ﹒ 運行時的連接支持來解析符號(因為庫是動態連接的) 你也可以寫自己的系統調用包裝器和自己的printf函數,並且在連接時(而不 是在運行時)進行符號解析,這樣可以消除對libc的依賴。 如果線程使用應用程序提供的堆棧,則線程庫不使用動態分配內存的辦法。 Thr_create(3T)函數可以由應用程序指定自己的堆棧。 6.2調試多線程應用程序 6.2.1一般的疏漏 以下列出可以導致多線程出錯的常見疏漏: ﹒ 給新線程傳遞參數時使用局部或全局變量 ﹒ 在沒有同步機制的保護下訪問全局內存 ﹒ 兩個線程以不同的順序去申請兩個資源導致死鎖(兩個線程各自佔有一個資源並相執不下) ﹒ 在同步保護中有隱藏的漏洞。例如可能有如下情況:一個有同步機制(例如互斥 鎖)保護的代碼段包含一個先釋放再重新獲得同步機制的函數調用,結果是全局內存 實際上沒有得到保護。 ﹒ 有隱匿的,重復或遞歸的大自動數組的使用可能導致問題,因為多線程程序的堆 棧容量比單線程程序有更多的限制。 ﹒ 指定的堆棧空間不夠。 ﹒ 沒有通過線程庫的調用指定堆棧。 注意,多線程程序(特別是有錯誤的)經常在相同輸入的情況下得到不同的結 果,因為線程調度的順序不同。 一般的,多線程bug具有統計性,而不是確定性。在調試時,跟蹤的辦法將會比 設斷點的辦法好些。 6.2.2使用adb 如果你在一個多線程程序當中綁定所有線程,一個線程和一個LWP是同步的。然 你通過如下支持多線程編程的adb命令訪問每一個線程。 表6-2 MT adb命令 ------------------------------------- pid:A 綁定在進程pid上,這將停止進程及其所有LWP ︰R 與進程分離,這將恢復進程及其所有LWP $L 顯示在(停止的)進程中所有的活動的LWP n:l 將焦點切換到第n號LWP $l 顯示當前焦點所在的LWP num:i 忽略信號碼為num的信號 6.2.3使用dbx 使用dbx,可以調試和執行用C++, ANSI C, FORTRAN和PASCAL的源程序。Dbx使用與SPARCworks? Debugger相同的命令,但使用標準終端(tty)接口。Dbx和 SPARCworks Debugger現在都支持多線程程序。 要得到dbx和Debugger的全面認識,請參考SunPro dbx(1) man page和 《Debugging a Program》用戶指南。 以下的dbx選項支持多線程。 表6-3 給MT程序使用的dbx選項 Cont at line[sig signo id] 在信號signo發生時繼續執行第line行。 參見dbx的命令語言的循環控制裡的continue。 如果有id參數,則指定繼續哪一個線程或LWP。 缺省設置為all。 Lwp 顯示當前LWP。切換到給定LWP[lwpid] Lwps 列出當前進程的所有LWP Next … tid 單步執行指定線程。如果一個函數調用被跳過, 所有的LWP在該函數調用期間重新開始???非 活動線程不能被單步執行 Next … lid 單步執行指定LWP。在跳過函數時並不隱含地恢 復所有的LWP。在該LWP上的線程是活動的。 Step … tid 單步執行指定線程。如果一個函數調用被跳過, 所有的LWP在該函數調用期間重新開始???非 活動線程不能被單步執行 Step … lid 單步執行指定LWP。在跳過函數時並不隱含地恢 復所有的LWP。 Stepi … lid 指定的LWP Stepi … tid 在LWP上的線程是活動的。 Thread 顯示當前線程。切換到線程tid。在以下情況中, 一個可選的tid指當前線程。 Thread -info[tid] 打印指定線程的所有已知情況。 Thread -locks[tid] 打印被指定線程控制的所有鎖 Thread -suspend[tid] 把指定線程置掛起狀態。 Thread -continue[tid] 使指定線程退出掛起狀態。 Thread -hide[tid] 隱藏指定(或當前)線程,在普通線程列表中 將不被顯示出來 Thread -unhide [tid] 解除指定線程的隱藏狀態 Allthread-unhide 解除所有線程的隱藏狀態 Threads 打印已知線程的列表 Threads-all 打印所有線程(包括通常不被打印的,zombies) All|filterthreads-mode 控制threads命令打印所有線程還是有選擇地列表 Auto|manualthreads-mode 使在GUI界面裡線程監控器(Thread Inspector) 線程列表得以自動更新 Threads -mode 顯示當前模式。Any of the previous forms can be followed by a thread or LWP ID to get the traceback for the specified entity.
(http://www.fanqiang.com)
進入【UNIX論壇】
|
|
| 相關文章 |
Solaris2.4 多線程編程指南7--編程指南 (2002-01-29 20:33:46) Solaris2.4 多線程編程指南6--編譯和調試 (2002-01-29 20:32:52) Solaris2.4 多線程編程指南5--安全和不安全的接口函數 (2002-01-29 20:32:05) Solaris2.4 多線程編程指南4--操作系統編程 (2002-01-29 20:29:36) Solaris2.4 多線程編程指南3--使用同步對象編程 (2002-01-29 20:28:07) Solaris2.4 多線程編程指南2--用多線程編程 (2002-01-29 20:26:32) Solaris2.4 多線程編程指南1--線程基礎 (2002-01-29 20:25:25) Linux下的多線程編程 (2001-08-11 09:05:00)
|
|
|
|
 |
★ 樊強制作 歡迎分享 ★ |