2010-08-09 20 views
8

मुझे भाषा निर्माण और कंपाइलर निर्माण में रूचि है, और यहां उदाहरण के माध्यम से काम कर रहे हैं: http://gnuu.org/2009/09/18/writing-your-own-toy-compiler/। लेखक एलएलवीएम 2.6 का उपयोग कर रहा था, और एलएलवीएम 2.7 के लिए कुछ बदलाव करने के बाद, मुझे संकलित करने के लिए सभी कोड जनरेशन कोड मिला। जब संकलक परीक्षण कोड खिला,एलएलवीएम कोड पीढ़ी seg गलती का कारण बनता है?

int do_math(int a) { 
    int x = a * 5 + 3 
} 

do_math(10) 

कार्यक्रम ठीक से काम करता है जब तक यह कोड को चलाने के लिए कोशिश करता है, जिस पर यह segfaults इशारा करते हैं। मैं अपने सिस्टम पर एलएलडीबी बनाने की प्रक्रिया में हूं, लेकिन इस बीच, इस एलएलवीएम एएसएम में कोई भी स्पष्ट सीजी गलती देखता है?

; ModuleID = 'main' 

define internal void @main() { 
entry: 
    %0 = call i64 @do_math(i64 10)     ; <i64> [#uses=0] 
    ret void 
} 

define internal i64 @do_math(i64) { 
entry: 
    %a = alloca i64         ; <i64*> [#uses=1] 
    %x = alloca i64         ; <i64*> [#uses=1] 
    %1 = add i64 5, 3        ; <i64> [#uses=1] 
    %2 = load i64* %a        ; <i64> [#uses=1] 
    %3 = mul i64 %2, %1        ; <i64> [#uses=1] 
    store i64 %3, i64* %x 
    ret void 
} 

उत्पादन सिर्फ है:

Segmentation fault 

मेरे मेहराब ओएस एक्स x86_64 है।

धन्यवाद।

उत्तर

15

मुझे एक ही समस्या है। मैंने लॉरेन के कंपाइलर को तोड़ दिया और सब कुछ निष्पादन को छोड़कर ठीक काम कर रहा था।

विभाजन गलती तथ्य की वजह से किया गया था कि:

ExecutionEngine * ee = EngineBuilder (मॉड्यूल) .create();

शून्य देता है। वास्तविक त्रुटि देखने के लिए, आपको त्रुटि स्ट्रिंग प्राप्त करने की आवश्यकता है:

std :: स्ट्रिंग त्रुटि; निष्पादन Engine * ee = Enginebuilder (मॉड्यूल) .setErrorStr (& त्रुटि) .create();

आपके मामले में आप शायद देखना चाहिए:

"(कोई लक्ष्य पंजीकृत हैं)

कि आप

कॉल करने की आवश्यकता को ठीक करने के लिए इस ट्रिपल के लिए लक्ष्य को ढूंढने में असमर्थ

प्रारंभिक लक्ष्य();

लेकिन यदि आपको मिलता है:

जेआईटी में लिंक नहीं किया गया है।

आप शामिल करना चाहिए:

LLVM/ExecutionEngine/MCJIT.h

जो JIT इंजन लिंक करेगा।

0

आपके द्वारा पोस्ट किया गया एलएलवीएम एएसएम आपके द्वारा प्रस्तुत सी कोड का सही अनुवाद नहीं है। आप एक स्टैक वैरिएबल के रूप में %a आवंटित कर रहे हैं, और उसके बाद से अनियमित डेटा लोड कर रहे हैं और इसका उपयोग कर रहे हैं। क्या आप चाहते हैं ऐसा करने के लिए अपना तर्क %a नाम दे रहा है और उस मान का उपयोग कर रहा है। बजाय इस कोड का उपयोग का प्रयास करें:

define internal i64 @do_math(i64 %a) { 
entry: 
    %x = alloca i64         ; <i64*> [#uses=1] 
    %1 = add i64 5, 3        ; <i64> [#uses=1] 
    %2 = mul i64 %a, %1        ; <i64> [#uses=1] 
    store i64 %2, i64* %x 
    ret void 
} 

इसके अलावा, आपके main() प्रोटोटाइप मेल नहीं खा सकते हैं कि आपके सी क्रम पुस्तकालय की उम्मीद है। और, उससे परे, आपको एहसास है कि आप परिणाम do_math() से वापस नहीं कर रहे हैं, है ना?

+0

कोड बिल्कुल 'सी कोड' नहीं है, यह एक सी जैसी भाषा है, जो मैंने ट्यूटोरियल में बनाया है। मैं समझता हूं कि 'do_math' फ़ंक्शन int को वापस नहीं करता है जैसा कि यह कहता है कि इसे करना चाहिए। एएसएम एक एएसटी और कुछ कोड जनरेशन कोड से उत्पन्न होता है, इसलिए मैं देखूंगा कि क्या मैं यह पता लगा सकता हूं कि यह अनियंत्रित डेटा का उपयोग क्यों कर रहा है। –

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