2013-02-19 13 views
9

के साथ 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

+0

पिच की आपकी गणना असामान्य लगती है। क्या आप इसे एक अजीब मूल्य n पर सेट करना चाहते हैं (ठीक है, uint16_t तत्वों की एक विषम संख्या)? इसे 4 या 8 के एकाधिक के लिए गोलाकार करने के लिए यह अधिक आम है। – simonc

+0

हां, यह जानबूझकर एक विषम संख्या पर सेट है। दुर्घटना भी पिच के साथ नहीं होती है ... और मैं खुद को क्यों नहीं समझ पा रहा हूं :) – Tisys

+1

जेनरेट किए गए असेंबली कोड की तुलना करें। साथ ही, आप व्यक्तिगत विकल्प '-O3' के साथ परीक्षण करना चाहते हैं यह देखने के लिए कि कौन सा अपराधी है (http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Optimize-Options देखें। एचटीएमएल # विकल्पों की सूची के लिए अनुकूलन विकल्प)। –

उत्तर

4

मेरा प्रश्न gcc Bugzilla पर रिचर्ड Blener से जवाब दिया गया है:

"आप uint16_t पर एक पॉइंटर को संदर्भित कर रहे हैं जो उस प्रकार के लिए पर्याप्त रूप से गठबंधन नहीं है। सी मानक इस पर प्रतिबंध लगाता है, जिसके परिणामस्वरूप अपरिभाषित व्यवहार होता है।"

मेरी राय में, इस अपरिभाषित व्यवहार के बारे में एक चेतावनी उत्पन्न की जानी चाहिए। कृपया यह भी ध्यान दें कि इस पोस्ट को टिप्पणियों में @jmetcalfe द्वारा यह स्पष्टीकरण भी दिया गया था।

+3

'reinterpret_cast' कंपाइलर को बताने का आपका तरीका है चुप रहो और पॉइंटर्स को बस जॉगल करें। Reinterpret_cast से जुड़े कई वस्तुतः ज्ञानी परिदृश्य हैं जो उनके लिए चेतावनियां लिखने की कोशिश कर रहे हैं व्यर्थ है। – thiton

+1

@Tisys, अपरिभाषित और निर्दिष्ट नहीं है, वे बहुत अलग हैं –

+0

@ जोनाथन, टिप्पणी के लिए धन्यवाद, तय :) – Tisys

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