線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:7000
推到 Plurk!
推到 Facebook!

關於Pure Virtual Function Call的除錯問題

尚未結案
jackwu
一般會員


發表:28
回覆:54
積分:16
註冊:2002-08-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-04-26 13:09:50 IP:211.75.xxx.xxx 未訂閱
各位先進:        我在我的程式中碰到了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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-04-26 19:33:25 IP:219.84.xxx.xxx 未訂閱
jackwu你好: 請問你錯誤的詳細訊息是什麼? C 幾乎是不可能在runtime出現pure virtual call的問題,大多會在compile time就擋下來了。如果你是使用bcb時遇到的,很有可能是在使用vcl時有bug。Delphi有metaclass的概念,相對而言在runtime產生pure virtual function call的錯誤的機率比較高。詳細問題來源可能要看錯誤的內容。
jackwu
一般會員


發表:28
回覆:54
積分:16
註冊:2002-08-18

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-04-27 03:32:16 IP:61.62.xxx.xxx 未訂閱
pwipwi你好: 錯誤的內容就只有 pure virtual function call而已,而產生此錯誤訊息的時機其實很不一定,我的程式是兩條Thread一直在Run,而使用到的vcl只有TImage而已,但是問題又在於,此一錯誤問題並不是一直會發生,而是整個程式在Run了一天兩天或者是Run了幾個小時就會出現,所以不知道該如何去Debug此一個問題,不知道有什麼樣的軟體可以在Runtime時期可以抓到此一個產生此錯誤訊息的程式碼,所以再麻煩各位先進提供一些意見,謝謝 另外請問一下,Delphi的metaclass的概念我不瞭解,是否可以請pwipwi大大在說明一下好嗎?謝謝
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-04-27 15:20:01 IP:219.84.xxx.xxx 未訂閱
如果能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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-04-27 16:58:09 IP:211.75.xxx.xxx 未訂閱
感謝pwipwi版主的回答: 看來這樣的一個錯誤是很難去Debug,因為在我的程式中,是不會去動態的產生TImage的物件,所以也不會去實體化TImage物件,但是會產生pure virtual function call,就令人無法瞭解其中的原因是什麼。 不過我程式是在做影像處理,所以Single Thread無法達到我的要求,所以還是要用Multi Thread的架構。 但還是很感謝版主大大的回應,讓我對於Delphi的機制有了多一點瞭解。 但針對於Delphi的Mateclass可以使用EurekaLog去Debug嗎?還是有其他的軟體呢? 謝謝
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-04-27 23:06:38 IP:219.84.xxx.xxx 未訂閱
在option中的link頁,打開debug library,compiler就會用原始碼compile。然後再把compiler整個切到debug模式。 run之後如果發生pure virtual function call,程式就會停在exception丟出的地方。這時打開call stack,就能知道是那個元件的那個函式叫到pure virtual function。
jackwu
一般會員


發表:28
回覆:54
積分:16
註冊:2002-08-18

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-04-28 18:15:29 IP:211.75.xxx.xxx 未訂閱
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

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-04-29 02:54:38 IP:219.84.xxx.xxx 未訂閱
你compile這段程式碼時,有沒有出現warning?
windblown
中階會員


發表:0
回覆:117
積分:98
註冊:2003-11-14

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-04-29 09:40:36 IP:61.229.xxx.xxx 未訂閱
對於這個 sample 的看法是: 當 B ( 甚至是 A ) 都還沒建立完成,馬上就去呼叫 virtual function, 是不是早了些? 畢竟 virtual 不比一般 function, 需要動態呼叫!!
jackwu
一般會員


發表:28
回覆:54
積分:16
註冊:2002-08-18

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-04-29 12:04:10 IP:211.75.xxx.xxx 未訂閱
引言: 你compile這段程式碼時,有沒有出現warning?
Compile完成,並無出現任何的warning
pwipwi
版主


發表:68
回覆:629
積分:349
註冊:2004-04-08

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-04-30 19:55:53 IP:219.84.xxx.xxx 未訂閱
你這段程式碼在設計上有些問題 物件在constructor中要避免使用本身的virtual function, 這是C 的rule之一。 另外錯誤的原因,windblown版友已經清楚的回答。
jackwu
一般會員


發表:28
回覆:54
積分:16
註冊:2002-08-18

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-05-04 02:36:06 IP:61.62.xxx.xxx 未訂閱
引言: 你這段程式碼在設計上有些問題 物件在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

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-09-23 12:02:56 IP:220.138.xxx.xxx 未訂閱
對不起炒個冷飯  因為我自己也遇到了 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

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-09-26 00:41:24 IP:219.84.xxx.xxx 未訂閱
dllee大大所提的問題也是我自已常常遇到的... Thread要改成ProcessMessages 我只能提一些有限的經驗來拋磚引玉。 一般我都像大家一樣在loop裡丟個ProcessMessages, 但是ThreadTimer我常常踢到reentry的問題~ 可以解決的方法是用一個變數來做guarding,不過情況各有不同, 用起來不一定都可行。尤其呼叫ProcessMessages後, 會跑到那個event很難掌握的一清二楚,不小心就出問題了。 或許站上其他前輩有不錯的經驗可以提供。 P.S.最近忙到吐血,快二個禮拜沒上站了,以致現在才看到這篇文章
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-09-26 10:32:19 IP:220.139.xxx.xxx 未訂閱
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

發送簡訊給我
#16 引用回覆 回覆 發表時間:2005-09-30 10:05:38 IP:220.139.xxx.xxx 未訂閱
我的 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
系統時間:2024-04-24 19:14:52
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!