2012-09-24 35 views
6

में बार-बार डिस्पैच मैसेज डब्ल्यू के साथ स्टैक ओवरफ़्लो त्रुटि नहीं समझा जाता है यह एक डेल्फी एप्लिकेशन है, लेकिन मुझे लगता है कि यह एक सामान्य विंडोज प्रोग्रामिंग प्रश्न है।मुझे कॉल स्टैक

मैंने सप्ताहांत में अपना आवेदन चलाना (डेल्फी आईडीई में) छोड़ दिया और अभी एक स्टैक ओवरफ़्लो खोजने के लिए वापस आ गया है।

ढेर इस तरह शुरू होता है ...

:75c4417e kernel32.GetDriveTypeW + 0x23 
:75c452ae kernel32.IsProcessorFeaturePresent + 0xa9 
:75c45272 kernel32.IsProcessorFeaturePresent + 0x6d 
:75c45248 kernel32.IsProcessorFeaturePresent + 0x43 
:7678410b KERNELBASE.LoadStringBaseExW + 0xc7 
:76678ed2 USER32.LoadStringW + 0x19 
:0040c4ae LoadResString + $4A 
uADStanDef.TADDefinition.Create(nil) 
uADStanDef.TADDefinition.CreateTemporary 
uADStanDef.TADConnectionDefTemporaryFactory.CreateObject 
uADStanFactory.TADManager.CreateInterface((1050358107, 62550, 16757, (168, 100, 178, 87, 60, 74, 32, 21)),(no value),True) 
uADStanFactory.ADCreateInterface((1050358107, 62550, 16757, (168, 100, 178, 87, 60, 74, 32, 21)),(no value),True) 
uADCompClient.TADCustomConnection.Create($2DB7EB0) 
fMainForm.TMainForm.ServerAliveTimerTimer($2E8DE38) <========== my code 
:004f1546 Winapi + $4F1546 
:00461316 Winapi + $461316 
:766762fa ; C:\Windows\syswow64\USER32.dll 
:76676d3a USER32.GetThreadDesktop + 0xd7 
:766777c4 ; C:\Windows\syswow64\USER32.dll 
:7667788a USER32.DispatchMessageW + 0xf 

तो, एक टाइमर समाप्त हो रही है, मैं (एक AnyDac घटक के) एक नई वस्तु और ढेर अतिप्रवाह बनाने रहा हूँ। कोड निश्चित रूप से वस्तु को मुक्त करता है। मैंने इसे उन लोगों के लिए नीचे जोड़ा है जो जांचना चाहते हैं, लेकिन मुझे नहीं लगता कि यह मेरा प्रश्न है।

ढेर तो जारी है

:7669cdfd ; C:\Windows\syswow64\USER32.dll 
:7669cf5c ; C:\Windows\syswow64\USER32.dll 
:766cf73c ; C:\Windows\syswow64\USER32.dll 
:766cfa18 ; C:\Windows\syswow64\USER32.dll 
:766cfb1f USER32.MessageBoxTimeoutW + 0x52 
:766cfd15 USER32.MessageBoxExW + 0x1b 
:766cfd57 USER32.MessageBoxW + 0x18 
:00549986 Vcl + $549986 
:00549aa2 Vcl + $549AA2 
:00549873 Vcl + $549873 
:00461316 Winapi + $461316 
:766762fa ; C:\Windows\syswow64\USER32.dll 
:76676d3a USER32.GetThreadDesktop + 0xd7 
:766777c4 ; C:\Windows\syswow64\USER32.dll 
:7667788a USER32.DispatchMessageW + 0xf 

तीन thoussand लाइन (!) के लिए दोहराया है कि ब्लॉक के साथ और मैं पता नहीं कि यह क्या है या क्या यह कर रहा है। यह तो समाप्त हो जाती है

StoreRoom.StoreRoom 
:75c4339a kernel32.BaseThreadInitThunk + 0x12 
:77eb9ef2 ntdll.RtlInitializeExceptionChain + 0x63 
:77eb9ec5 ntdll.RtlInitializeExceptionChain + 0x36 

मुझे कोई tunderstand है कि बार-बार ढेर के सभी - किसी सलाह दे सकते हैं?

procedure TMainForm.ServerAliveTimerTimer(Sender: TObject); 
begin 
    try 
     ADConnection := TADConnection.Create(Self); <======= stack overflow here 
     ADConnection.DriverName := 'mysql'; 
     ADConnection.Params.Add('Server=' + MAIN_STOREROOM_IP_ADDRESS); 
     // other params, such as password, removed for posting 
     ADConnection.Connected := True; 

    except 
     on E : Exception do 
     begin 
     ADConnection.Free(); 
     theDialogForm := TDialogFormForm.Create(Nil); 
     theDialogForm.ShowTheForm('Database problem'+#13+#10+''+#13+#10+ 
            E.ClassName+#13+#10+E.Message);  
     StopTheApplication(); <===== just calls ExitProcess(0); 
     Exit;      as I had problems with Halt elsewhere in the code 
     end; 
    end; 

    if isMainStoreRoom then 
    begin 
     CheckIfStoreRoomIsAlive(SECONDARY_STOREROOM_IP_ADDRESS); 
    end 
    else 
    begin 
     CheckIfStoreRoomIsAlive(MAIN_STOREROOM_IP_ADDRESS); 
    end; 

    try // Now, update our own timestamp 
     timestamp := GetCurrentUnixTimeStamp(); 
     ADConnection.ExecSQL('UPDATE server_status SET alive_timestamp="' + IntToStr(timestamp) + '" WHERE ip_address="' + ipAddress + '"'); 

    except 
     on E : Exception do 
     begin 
     ADConnection.Free(); 
     Exit; 
     end; 
    end; 

    ADConnection.Free(); 
end;  // ServerAliveTimerTimer() 
+4

+1। – lkessler

+2

ADConnection का उपयोग करने के बजाय आपको हर बार कनेक्शन क्लास बनाने की आवश्यकता क्यों है। कनेक्ट किया गया True/False? रनटाइम पर डेटाबेस कनेक्शन सेटिंग्स बदलते हैं? – pani

+0

प्रश्न को संदिग्ध रूप से "मैं स्टैक ओवरफ्लो समझ में नहीं आता" नामक था, लेकिन किसी ने इसे संपादित करने के लिए इसे संपादित किया (सभी पसंद करने वालों के लिए +1) – Mawg

उत्तर

15

आपका ढेर:

मेरे कोड (और आप की astutute जो लगता है कि मेरी अपवाद हैंडलिंग एक संवाद दिखाया जा रहा है के लिए, कि एक TForm जो बंद कर देता है जब उपयोगकर्ता क्लिक करता है ठीक है) ओवरफ्लो MessageBox() को दोहराए जाने वाले विंडो संदेश के जवाब में ओवर और ओवर कहा जाता है। आंतरिक रूप से, MessageBox() अपना स्वयं का संदेश लूप चलाता है, जो स्पष्ट रूप से उसी संदेश को संसाधित और प्रेषित कर रहा है। यह एक टाइमर इंगित कर सकता है जो भटक ​​गया है। जब आप पहली बार अपना OnTimer ईवेंट हैंडलर दर्ज करते हैं, और फिर बाहर निकलने से पहले टाइमर को फिर से सक्षम करते हैं, तो मैं दृढ़ता से सुझाव देता हूं कि आप अपना टाइमर अक्षम करें।

एक अलग नोट पर, StopTheApplication() को ExitProcess() (या यहां तक ​​कि Halt()) को सीधे कॉल नहीं करना चाहिए। इसके बजाय Application.Terminate() का उपयोग करें। एक स्टैक ओवरफ़्लो के बारे में एक स्टैक ओवरफ़्लो प्रश्न के लिए

+0

+1 धन्यवाद, @ रेमी। मैं यह उल्लेख करने में असफल रहा कि मैं आईडीई में दौड़ रहा था। क्या संदेशबॉक्स() से कॉल उस से हो सकती है? मैं इसे बिल्कुल नहीं कहता हूं। मैं MessageDlg() को कॉल करता हूं, लेकिन किसी भी टाइमर हैंडलर में नहीं - उन में मैं कस्टम त्रुटि फॉर्म बना और दिखाता हूं। मेरे पास केवल तीन टाइमर हैं और दूसरे दो के लिए हैंडलर कोड मैंने पोस्ट किए गए से छोटा है। मैं टाइमर अक्षम/सक्षम करने के बारे में अपना मुद्दा लेता हूं, लेकिन सबसे छोटा (दिखाया गया) 8 सेकंड है। कुछ डी/बी एक्सेस 8 सेकंड नहीं ले सकते हैं। – Mawg

+0

रुको ... मैं MessageBox() को कॉल नहीं करता, लेकिन शायद डेटाबेस त्रुटि होने पर, AnyDac कोड करता है ... लेकिन फिर भी, यह लूपिंग क्यों होगा? AnyDac अब तक अच्छी तरह से परीक्षण किया जाता है।मैं इसे टाइमर अक्षम/सक्षम कोड के साथ एक और रन दूंगा और समस्या को तेज करने की कोशिश करने के लिए टाइमर लम्बाई को छोटा कर दूंगा यदि यह फिर से होता है – Mawg

+2

'संदेश बॉक्स()' को 'एप्लिकेशन.मेसेजबॉक्स()' से कॉल किया जा रहा है कॉल स्टैक में वीसीएल कोड के कुछ टुकड़े द्वारा बुलाया जा रहा है। उदाहरण के लिए, एप्लिकेशन.मेसेजबॉक्स() को कभी-कभी अपवाद हैंडलर द्वारा बुलाया जाता है। कहना है कि आपका कॉल स्टैक वीसीएल के फ़ंक्शन नाम प्रदर्शित नहीं करता है। क्या आप डीबग के बजाय रिलीज के लिए संकलित कर रहे हैं? किसी भी मामले में, जो कुछ भी 'MessageBox()' को बुला रहा है, उसे स्पष्ट रूप से पुन: प्रस्तुत करने के लिए लिखा नहीं गया है और रिकर्सिव लूप में फंस रहा है, जिससे प्रत्येक नेस्टेड कॉल के साथ स्टैक पर अधिक से अधिक डेटा को 'संदेशबॉक्स()' तक स्टैक ओवरफ्लो तक दबाया जाता है । –

संबंधित मुद्दे