बदलने के कारण मुझे याद आ रही है कि मुझे स्मृति भ्रष्टाचार की समस्या है। कई घंटों के बाद डिबगिंग और कोशिश करने के बाद मुझे लगता है कि मुझे कुछ मिला है।सिस्टम में मेमोरी भ्रष्टाचार। 8087 सीडब्ल्यू मोड (पीएनजी + स्ट्रेचब्लैट)
उदाहरण के लिए: मैं एक साधारण स्ट्रिंग काम करते हैं:
sTest := 'SET LOCK_TIMEOUT ';
हालांकि, कभी-कभी परिणाम हो जाता है:
sTest = 'SET LOCK'#0'TIMEOUT '
तो, _ द्वारा एक 0 बाइट की जगह हो जाता है।
मैंने सिस्टम में यह एक बार हो रहा है (पुन: उत्पादित करना मुश्किल है, समय पर निर्भर है)। मेव फ़ंक्शन, जब यह तेज़ मेमोरी प्रतिलिपि के लिए एफपीयू स्टैक (फिल्ड, फिस्ट) का उपयोग करता है (9 से 32 बाइट्स तक ले जाने के):
...
@@SmallMove: {9..32 Byte Move}
fild qword ptr [eax+ecx] {Load Last 8}
fild qword ptr [eax] {Load First 8}
cmp ecx, 8
jle @@Small16
fild qword ptr [eax+8] {Load Second 8}
cmp ecx, 16
jle @@Small24
fild qword ptr [eax+16] {Load Third 8}
fistp qword ptr [edx+16] {Save Third 8}
...
एफपीयू देख सकते हैं और 2 स्मृति डिबग दृश्य (डेल्फी का उपयोग करना -> देखें -> डीबग -> सीपीयू -> मेमोरी) मैं यह जा रहा गलत ... एक बार ... लेकिन पुन: पेश नहीं कर सका देखा ...
आज सुबह मैंने 8087 सीडब्ल्यू मोड के बारे में कुछ पढ़ा, और हाँ, अगर यह $ 27FI में बदल गया है तो स्मृति भ्रष्टाचार प्राप्त करें! आम तौर पर यह $ 133F है:
$ 133F और $ 027F के बीच अंतर यह है कि $ 027F (कम सटीक गणना कर (विस्तारित की जगह में डबल करने के लिए सीमित) और विभिन्न इनफिनिटी से निपटने के लिए एफपीयू सेट जो इस्तेमाल किया गया था है पुराने एफपीयू के लिए, लेकिन अब और उपयोग नहीं किया जाता है)।
ठीक है, अब मैंने पाया क्यों नहीं बल्कि जब!
if Get8087CW = $27F then //normally $1372?
if MainThreadID = GetCurrentThreadId then //only check mainthread
DebugBreak;
मैं "प्रोफाइल" कुछ इकाइयों और dll के और बिंगो (ढेर देखें)::
मैं एक साधारण जांच (ताकि सभी कार्यों में प्रवेश करने और छोड़ने के पर जाँच कर रहे हैं) के साथ मेरी AsmProfiler की कार्यप्रणाली बदल
Windows.StretchBlt(3372289943,0,0,514,345,4211154027,0,0,514,345,13369376)
pngimage.TPNGObject.DrawPartialTrans(4211154027,(0, 0, 514, 345, (0, 0), (514, 345)))
pngimage.TPNGObject.Draw($7FF62450,(0, 0, 514, 345, (0, 0), (514, 345)))
Graphics.TCanvas.StretchDraw((0, 0, 514, 345, (0, 0), (514, 345)),$7FECF3D0)
ExtCtrls.TImage.Paint
Controls.TGraphicControl.WMPaint((15, 4211154027, 0, 0))
तो यह StretchBlt में हो रहा है ...
अब क्या करें? क्या यह विंडोज़ की गलती है, या पीएनजी में एक बग है (डी 2007 में शामिल)? या सिस्टम है। मेव फ़ंक्शन विफल नहीं है?
नोट: बस पुन: पेश करने की कोशिश कर काम नहीं करता है:
Set8087CW($27F);
sSQL := 'SET LOCK_TIMEOUT ';
यह अधिक विदेशी प्रतीत हो रहा है ... लेकिन 'Get8087CW = $ 27F' पर DebugBreak से मैं इसे एक अन्य स्ट्रिंग पर पुन: पेश कर सकता : एफपीयू भाग 1: एफपीयू भाग 2: एफपीयू भाग 3: एफपीयू अंतिम: भ्रष्ट !:
नोट 2: शायद सिस्टम में एफपीयू स्टैक को मंजूरी दे दी जानी चाहिए।
+1। मुझे जवाब नहीं पता, लेकिन मेरी समस्या निवारण रणनीति हमेशा संभावनाओं को खत्म कर समस्या को सरल बनाना है। देखें कि क्या आप पीएनजी को नए lib के साथ हटाकर या बदलकर पीएनजी पर या बाहर कर सकते हैं। –
संबंधित प्रश्न: http://stackoverflow.com/questions/1466229/what-can-cause-system-move-to-occasionaly-give-wrong-results – mghie