के साथ 16bpp छवि भरते समय क्रैश एक स्थिर मूल्य (1024) के साथ 32x32 16bpp छवि को भरने के लिए मैंने एक बहुत ही सरल कोड लिखा है। छवि बफर std::vector
द्वारा होस्ट किया गया है। मेरी छवि के पिच/स्ट्रइड (यानी दो लगातार लाइनों के बीच बाइट्स की संख्या) पूरी लाइन को पकड़ने के लिए काफी बड़ी है, लेकिन एक विषम संख्या सेट है। यहां मेरा कोड है:-O3 ऑप्टिमाइज़ेशन और अजीब पिच
#include <vector>
#include <stdint.h>
int main()
{
int width = 32;
int height = 32;
int pitch = width * 2 + 1;
std::vector<uint8_t> image(height * pitch);
uint8_t* buffer = &image[0];
for (int y = 0; y < height; y++)
{
uint16_t* p = reinterpret_cast<uint16_t*>(buffer + y * pitch);
for (int x = 0; x < width; x++, p++)
{
*p = 1024;
}
}
}
मैं जीसीसी 4.6.1 (उबंटू 11.10) के साथ लिनक्स x86_64 का उपयोग कर रहा हूं। कोड -O0
, -O1
और -O2
अनुकूलन स्तर के साथ ठीक चलाता है। Valgrind किसी भी पहुंच उल्लंघन की रिपोर्ट नहीं करता है। हालांकि, जैसे ही मैं -O3
करने के लिए स्विच या ऑटो vectorization, कार्यक्रम दुर्घटनाओं के लिए -ftree-vectorize
विकल्प का उपयोग के रूप में:
# g++ -g -O3 ./test.cpp -Wall -pedantic && ./a.out
Segmentation fault
# g++ -g -O2 -ftree-vectorize ./test.cpp -Wall -pedantic && ./a.out
Segmentation fault
न तो gdb है और न ही valgrind किसी भी उपयोगी जानकारी प्रदान करते हैं:
# valgrind ./a.out
==3840== Memcheck, a memory error detector
==3840== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==3840== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==3840== Command: ./a.out
==3840==
==3840==
==3840== Process terminating with default action of signal 11 (SIGSEGV)
==3840== General Protection Fault
==3840== at 0x4005B3: main (test.cpp:18)
==3840==
==3840== HEAP SUMMARY:
==3840== in use at exit: 2,080 bytes in 1 blocks
==3840== total heap usage: 1 allocs, 0 frees, 2,080 bytes allocated
==3840==
==3840== LEAK SUMMARY:
==3840== definitely lost: 2,080 bytes in 1 blocks
==3840== indirectly lost: 0 bytes in 0 blocks
==3840== possibly lost: 0 bytes in 0 blocks
==3840== still reachable: 0 bytes in 0 blocks
==3840== suppressed: 0 bytes in 0 blocks
==3840== Rerun with --leak-check=full to see details of leaked memory
==3840==
==3840== For counts of detected and suppressed errors, rerun with: -v
==3840== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
Segmentation fault
दुर्घटना ऐसा नहीं होता है जब मैं -m32
जीसीसी ध्वज के साथ 32 बिट बाइनरी पर स्विच करता हूं। यह तब भी नहीं होता है जब मैं एक पिच का उपयोग करता हूं (उदा। pitch = width * 2 + 2
)। क्या कोई मुझे मेरे कोड में (निश्चित रूप से बेवकूफ) त्रुटि को खोजने में मदद कर सकता है? अग्रिम में बहुत धन्यवाद!
अद्यतन: जोनाथन ने सुझाव दिया के रूप में, मैं सिर्फ जीसीसी डेवलपर्स के लिए इस समस्या को सूचित किया है: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56392
पिच की आपकी गणना असामान्य लगती है। क्या आप इसे एक अजीब मूल्य n पर सेट करना चाहते हैं (ठीक है, uint16_t तत्वों की एक विषम संख्या)? इसे 4 या 8 के एकाधिक के लिए गोलाकार करने के लिए यह अधिक आम है। – simonc
हां, यह जानबूझकर एक विषम संख्या पर सेट है। दुर्घटना भी पिच के साथ नहीं होती है ... और मैं खुद को क्यों नहीं समझ पा रहा हूं :) – Tisys
जेनरेट किए गए असेंबली कोड की तुलना करें। साथ ही, आप व्यक्तिगत विकल्प '-O3' के साथ परीक्षण करना चाहते हैं यह देखने के लिए कि कौन सा अपराधी है (http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Optimize-Options देखें। एचटीएमएल # विकल्पों की सूची के लिए अनुकूलन विकल्प)। –