मैं कोड के इस छोटे-से स्निपेट है (इस समस्या का एक न्यूनतम काम कर उदाहरण मेरे पास है):अजीब व्यवहार सक्षम
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void xorBuffer(unsigned char* dst, unsigned char* src, int len)
{
while (len != 0)
{
*dst ^= *src;
dst++;
src++;
len--;
}
}
int main()
{
unsigned char* a = malloc(32);
unsigned char* b = malloc(32);
int t;
memset(a, 0xAA, 32);
memset(b, 0xBB, 32);
xorBuffer(a, b, 32);
printf("result = ");
for (t = 0; t < 32; t++) printf("%.2x", a[t]);
printf("\n");
return 0;
}
इस कोड को माना जाता है दो 32- अनन्य या के प्रदर्शन करने के लिए बाइट मेमोरी बफर (अवधारणात्मक रूप से, यह a = a^b
करना चाहिए)। 0xAA^0xBB = 0x11 के बाद से, इसे "11" बार-बार प्रिंट करना चाहिए।
मेरे समस्या यह है, जब मैं इस MinGW-जीसीसी (विंडोज़) के तहत संकलन, इस डिबग मोड (एक भी अनुकूलन नहीं), लेकिन xorBuffer पाश के माध्यम से एक SIGILL रास्ते के मध्य में के साथ दुर्घटनाओं में पूरी तरह से काम करता है जब -O3 से शुरू अनुकूलन सक्षम हैं। इसके अलावा, अगर मैं अपमानजनक लूप में एक printf डालता हूं, तो यह पूरी तरह से फिर से काम करेगा। मुझे संदेह है कि भ्रष्टाचार ढेर है लेकिन मैं नहीं देखता कि मैं यहां क्या कर रहा हूं।
ऑप्टिमाइज़ेशन सक्षम के साथ जीडीबी के साथ डीबग करने का प्रयास करना एक खो गया कारण है क्योंकि सभी जीडीबी मुझे दिखाता है कि हर चर के लिए मुझे "परिवर्तनीय अनुकूलित" है (और, ज़ाहिर है, अगर मैं एक वैरिएबल आउट करने की कोशिश करता हूं और प्रिंट करता हूं, तो यह अचानक काम करेगा)।
क्या कोई जानता है कि बिल्ली यहां क्या चल रहा है? मैंने इस मुद्दे पर बहुत लंबा आवास बिताया है, और मुझे इसे आगे बढ़ने के लिए ठीक से ठीक करने की ज़रूरत है। मेरा अनुमान है कि मुझे कुछ मौलिक सी पॉइंटर ज्ञान याद आ रहा है, लेकिन मेरे लिए कोड सही दिखता है। यह बफर वृद्धि से हो सकता है, लेकिन जहां तक मुझे पता है, sizeof(unsigned char) == 1
, इसलिए यह प्रत्येक बाइट को एक-एक करके जा रहा है।
इसके लायक होने के लिए, कोड मेरे लिनक्स बॉक्स पर जीसीसी पर अनुकूलन के साथ भी काम करता है।
तो ... यहां क्या सौदा है? धन्यवाद!
के रूप में अनुरोध किया है, पूरे कार्यक्रम के विधानसभा उत्पादन:
-O2 के साथ: clicky
-O3 के साथ: clicky
मैं जीसीसी 4.6.2 पर इस व्यवहार का निरीक्षण (के साथ चल रहा MinGW)
'O2' का उपयोग करने के बारे में क्या? 'ओ 3' बहुत जोखिम भरा है। सिगिल का अर्थ है - सिग्नल, अवैध निर्देश के कारण। मुझे एक कंपाइलर बग की तरह लग रहा है। या मुझे कुछ याद आ रही है। –
यह मेरे जीसीसी 4.4.3 पर सही काम करता है। यदि कोई भी कुछ भी नहीं देखता है, तो आप दोनों मामलों में - 'ओ 3' और 'ओ 2' के साथ जीसीसी द्वारा उत्पादित असेंबली कोड दिखाने की कोशिश कर सकते हैं (यदि यह ठीक काम करता है, अन्यथा - अनुकूलन का निम्न स्तर) –
@ किर्किलकिरोव यह बग मूल रूप से उच्च प्रदर्शन वाली लाइब्रेरी में खोजा गया था, इसलिए ओ 2 पर जाने के लिए वास्तव में हमारे लिए सबसे अच्छा समाधान नहीं है - बेशक अगर यह एक कंपाइलर बग है तो हम ठीक होने तक ओ 2 तक गिर जाएंगे। मैं बिना किसी अनुकूलन के उत्पादन और ओ 3 के साथ असेंबली पोस्ट करूंगा। – Thomas