關於Pure Virtual Function Call的除錯問題 |
尚未結案
|
jackwu
一般會員 發表:28 回覆:54 積分:16 註冊:2002-08-18 發送簡訊給我 |
各位先進: 我在我的程式中碰到了Pure virtual function call 的問題,但是在我自己寫的程式中,完全沒有使用到Virtual function。也有上網找過資料,在Microsoft中有找到一篇關於此種錯誤的說明:http://support.microsoft.com/default.aspx?scid=kb;en-us;125749#toc
雖然已經知道,此問題是如何產生的,但是卻不知道是哪裡的的程式行會造成此總錯誤的發生,小弟已經嘗試的使用EurekaLog除錯軟體,但是都抓不到此種錯誤,看來這種錯誤也不是Execption,所以用EurekaLog也沒有辦法抓到錯誤的程式行。
請教各位先進,這樣的錯誤訊息,我應該如何Debug呢?還是有其他可以在BCB上應用的Debug軟體,可以幫助我去找出錯誤的程式碼呢? 謝謝
|
pwipwi
版主 發表:68 回覆:629 積分:349 註冊:2004-04-08 發送簡訊給我 |
|
jackwu
一般會員 發表:28 回覆:54 積分:16 註冊:2002-08-18 發送簡訊給我 |
pwipwi你好:
錯誤的內容就只有 pure virtual function call而已,而產生此錯誤訊息的時機其實很不一定,我的程式是兩條Thread一直在Run,而使用到的vcl只有TImage而已,但是問題又在於,此一錯誤問題並不是一直會發生,而是整個程式在Run了一天兩天或者是Run了幾個小時就會出現,所以不知道該如何去Debug此一個問題,不知道有什麼樣的軟體可以在Runtime時期可以抓到此一個產生此錯誤訊息的程式碼,所以再麻煩各位先進提供一些意見,謝謝
另外請問一下,Delphi的metaclass的概念我不瞭解,是否可以請pwipwi大大在說明一下好嗎?謝謝
|
pwipwi
版主 發表:68 回覆:629 積分:349 註冊:2004-04-08 發送簡訊給我 |
如果能Screen Print下錯誤的dialog,可以幫助判斷是不是VCL的錯誤。 另外C 不太可能會發生這個錯誤是因為C使用的是靜態型別的架構。任何物件在產生時,有什麼member data,member function都是確定的,因此abstract base class是不可能被compiler產生出來的,連pure virtual function都是不產生的(因為他一定會override)。所以在C 的程式碼的中,可以說根本不可能呼叫到pure virtual function(因為他本身就不存在)。 Delphi使用了metaclass來做到動態的型別。一個class的型別可以在runtime時才決定,是非常有彈性而且強大的做法。概念上就好像工人(program)按圖(metaclass)施工,做出一個成品(class)。 這樣的架構這存在一個可能的錯誤點:以base class的型別來看,裡面可能包含要被override的pure virtual function,就好像在設計圖上有些地方註明了”此部分結構請參考某某圖”。但...萬一那個”某某圖”掉了,或是沒有寫出來,只要一被呼叫到就會出現pure virtual function call的錯誤。 一般在VCL會遇到這個錯誤,最大的可能是不當的使用繼承和多型。比如TStrings是不應該被實體化的(他有pure virtual function),但是在Delphi的架構下,他有可能會被產生出來。 另外,你的程式如果可以不要用到multithread,.就不要用他.因為任何的規則遇上multithread都有可能會出錯:S。而且大部份的程式以ProcessMessages的手法就可以在single thread下取代multithread的功能。(只除了網路程式非用不可外...) 建議你用singlethread,或許問題就解決了。
|
jackwu
一般會員 發表:28 回覆:54 積分:16 註冊:2002-08-18 發送簡訊給我 |
感謝pwipwi版主的回答: 看來這樣的一個錯誤是很難去Debug,因為在我的程式中,是不會去動態的產生TImage的物件,所以也不會去實體化TImage物件,但是會產生pure virtual function call,就令人無法瞭解其中的原因是什麼。
不過我程式是在做影像處理,所以Single Thread無法達到我的要求,所以還是要用Multi Thread的架構。
但還是很感謝版主大大的回應,讓我對於Delphi的機制有了多一點瞭解。
但針對於Delphi的Mateclass可以使用EurekaLog去Debug嗎?還是有其他的軟體呢?
謝謝
|
pwipwi
版主 發表:68 回覆:629 積分:349 註冊:2004-04-08 發送簡訊給我 |
|
jackwu
一般會員 發表:28 回覆:54 積分:16 註冊:2002-08-18 發送簡訊給我 |
pwipwi大大:
小弟有依照你的方法去做一遍,可以從call stack看到一些資訊,但是還是無法知道是哪一個函式叫到pure virtual function。下面有一段Sample code,可否請大大幫我測試看看呢?
謝謝
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- class A; void fcn( A* ); class A { public: virtual void f() = 0; A() { fcn( this ); } }; class B : public A { void f() { } }; void fcn( A* p ) { p->f(); }; void __fastcall TForm1::Button1Click(TObject *Sender) { B b; }call stack中的資訊 40009729 C:\WINDOWS\system32\rtl60.bpl 40013541 C:\WINDOWS\system32\rtl60.bpl 40005C69 C:\WINDOWS\system32\rtl60.bpl 7C92378B ntdll.dll 7C92EAFA ntdll.dll 謝謝 |
pwipwi
版主 發表:68 回覆:629 積分:349 註冊:2004-04-08 發送簡訊給我 |
|
windblown
中階會員 發表:0 回覆:117 積分:98 註冊:2003-11-14 發送簡訊給我 |
|
jackwu
一般會員 發表:28 回覆:54 積分:16 註冊:2002-08-18 發送簡訊給我 |
|
pwipwi
版主 發表:68 回覆:629 積分:349 註冊:2004-04-08 發送簡訊給我 |
|
jackwu
一般會員 發表:28 回覆:54 積分:16 註冊:2002-08-18 發送簡訊給我 |
引言: 你這段程式碼在設計上有些問題 物件在constructor中要避免使用本身的virtual function, 這是C 的rule之一。 另外錯誤的原因,windblown版友已經清楚的回答。pwipwi大大: 這個只是我所寫的Sample Code,主要的目的只是希望可以從此一個Sample找出可以Debug此一問題的方法,但是看起來是不可行的。況且我的程式中,並沒有像Sample Code真的會使用到Virtual function,所以才不知道要如何去Debug,我在另外想辦法好了,還是謝謝pwipwi大大及windblown大大指教。 謝謝 |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
對不起炒個冷飯
因為我自己也遇到了 src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=24641564&CC=551096"> 另外,關於 ProcessMessages 的方式,最近也在把原本多執行緒內的一些
處理函式改成 PostMessage/SendMessage 的方式,但是發現,兩者混用也
有意想不到的效果
想請教 > > < href="http://free.greenworld.com.tw/~dllee/" target="blank">吃軟也吃硬 dllee.ktop.com.tw dllee's sharespace Beckhoff Fieldbus
------
http://www.ViewMove.com |
pwipwi
版主 發表:68 回覆:629 積分:349 註冊:2004-04-08 發送簡訊給我 |
dllee大大所提的問題也是我自已常常遇到的...
Thread要改成ProcessMessages
我只能提一些有限的經驗來拋磚引玉。 一般我都像大家一樣在loop裡丟個ProcessMessages,
但是ThreadTimer我常常踢到reentry的問題~
可以解決的方法是用一個變數來做guarding,不過情況各有不同,
用起來不一定都可行。尤其呼叫ProcessMessages後,
會跑到那個event很難掌握的一清二楚,不小心就出問題了。
或許站上其他前輩有不錯的經驗可以提供。 P.S.最近忙到吐血,快二個禮拜沒上站了,以致現在才看到這篇文章
|
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
pwipwi 大大您客氣了 < >
我自己思考了很久,到底要如何發問... 自己都還沒有理出頭緒,所以還沒有提問。< >
如果只是單純的 Message 化,把 ThreadTimer 直接改用 TTimer 就變成 Windows Message 了,TTimer 底層也是用系統的 TIMER 事件,只是,用 TTimer 就無法調優先權以及比較不準的問題。
如果還是使用 ThreadTimer 只是在 Timer 內只發 Message 不作事,那又沒有好方法去判定到底每次 ThreadTimer 觸發時都要發 Message (有可能造成累積多次 Message 還未處理的狀況),還是得等前次 Message 作完再發下一次 Message... 判斷的不好,可能就死在那裡 上週花了很多時間再找我自己的 >
所以 > < href="http://free.greenworld.com.tw/~dllee/" target="blank">吃軟也吃硬 dllee.ktop.com.tw dllee's sharespace Beckhoff Fieldbus VMASK
------
http://www.ViewMove.com |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
我的 Pure Virtual Function called 的問題解決了,
原本只有加入無謂的判斷還是在一段時間後就失效... 先說明狀況:
1. A元件 繼承 B元件
2. 在執行緒內有叫用A/B元件的 Pure Virtual Function
3. 在 delete A 時,執行緒還在執行,因此叫用了 Pure Virtual Function 解決方法:
在 delete A 之前,先把執行緒 delete 掉,
確認執行緒己不再執行了,再 delete A 就沒有問題了。 我最後就是這樣解決的。 C# 初學者請多指教 < href="http://free.greenworld.com.tw/~dllee/" target="blank">吃軟也吃硬 dllee.ktop.com.tw dllee's sharespace Beckhoff Fieldbus VMASK
------
http://www.ViewMove.com |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |