2015-02-17 7 views
18

के अंदर एक पैकेज मॉड्यूल में आईओ डिबगिंग IHaskell में निम्न स्तर के आईओ (लाइब्रेरी बाइंडिंग के लिए) कर रहा हूं और एक सेगफॉल्ट का अनुभव कर रहा हूं। मैं का उपयोग करना चाहते GHCi के : तोड़ने यह पता लगाने की क्या हो रहा है, लेकिन यहाँ क्या होता है:जीएचसीआई

> import SDL 
> :break SDL.setPaletteColors 
cannot set breakpoint on setPaletteColors: module SDL.Video.Renderer is not interpreted 

के बाद से अपमानजनक कोड एक बाहरी पैकेज में मेरे अपने मॉड्यूल के अंदर, बल्कि एक मॉड्यूल के अंदर नहीं है, इसे संकलित कोड के रूप में लोड किया गया है और स्पष्ट रूप से मैं का उपयोग नहीं कर सकता: संकलित मॉड्यूल पर तोड़ें।

GHCi manual इस बात की पुष्टि करता है और एक संकेत प्रदान करता है:

वहाँ एक प्रमुख प्रतिबंध नहीं है: breakpoints और एकल स्टेपिंग व्याख्या मॉड्यूल में ही उपलब्ध हैं; संकलित कोड डीबगर [5] के लिए अदृश्य है।

[5] ध्यान दें कि पैकेज में केवल संकलित कोड होता है, इसलिए पैकेज को डीबग करने के लिए इसके स्रोत को ढूंढना और सीधे लोड करना आवश्यक है।

की यह सीधे कोशिश करते हैं:

> :load some_path/sdl2/src/SDL/Video/Renderer.hs 

some_path/sdl2/src/SDL/Video/Renderer.hs:101:8: 
Could not find module ‘Control.Monad.IO.Class’ 
It is a member of the hidden package ‘transformers-0.3.0.0’. 
Perhaps you need to add ‘transformers’ to the build-depends in your .cabal file. 
Use -v to see a list of the files searched for. 

मैं अपने .cabal फाइल करने के लिए निर्भरता में जोड़ सकते हैं, लेकिन यह पहले से ही गलत लगता है।

> :load some_path/sdl2/src/SDL/Video/Renderer.hs 

some_path/sdl2/src/SDL/Video/Renderer.hs:119:8: 
Could not find module ‘SDL.Internal.Numbered’ 
it is a hidden module in the package ‘sdl2-2.0.0’ 
Use -v to see a list of the files searched for. 

मैं उन मॉड्यूल सार्वजनिक कर सकता है, लेकिन इस स्थिति में यह काम करने के लिए एक बहुत ही अजीब तरह से लगता है और मैंने नहीं किया: एक बार मुझे लगता है कि किया है (शायद पैकेज .cabal संशोधित करके?) आगे आगे बढ़ो।

संपादित करें:

मैं वास्तव में है कि कोशिश की और चौंकाने परिणाम मिला:

> :load some_path/sdl2/src/SDL/Video/Renderer.hs 
[1 of 1] Compiling SDL.Video.Renderer (some_path/sdl2/src/SDL/Video/Renderer.hs, interpreted) 
Ok, modules loaded: SDL.Video.Renderer. 
> :break SDL.setPaletteColors 
cannot set breakpoint on SDL.setPaletteColors: module SDL.Video.Renderer is not interpreted 

मेरे (अशिक्षित) अनुमान: ऐसा इसलिए है क्योंकि बाहरी मॉड्यूल अभी भी एक द्विआधारी के रूप में मेरे कोड से जुड़ा हुआ है, और इसे गतिशील तरीके से गतिशील रूप से लोड करना उसमें बदलाव नहीं करता है। क्या एक बाहरी पैकेज में आईओ डिबग करने के लिए एक अच्छा तरीका है:


तो, सवाल योग के लिए?

अतिरिक्त नोट्स:

  1. मैं पैकेज मैं डिबग करने की जरूरत के लिए स्रोत है; वास्तव में, यह कबाल सैंडबॉक्स एड-स्रोत के साथ परियोजना के लिए जोड़ दिया गया है

  2. GHCi का उपयोग कर पैकेज स्रोत के निशान को जोड़ने के लिए किया जाएगा के लिए एक वैकल्पिक विकल्प है, लेकिन यह एक दुर्भाग्यपूर्ण विकल्प है, क्योंकि यह की रखता शामिल प्रत्येक संशोधन पर पैकेज (जब भी मुझे निष्पादन के बारे में अधिक जानकारी चाहिए और निशान को संशोधित करें), और यह वास्तव में लंबा समय लगता है। जीएचसीआई के साथ इंटरेक्टिव डिबगिंग इस नौकरी के लिए एक बेहतर उपकरण प्रतीत होता है, अगर केवल मुझे पता था कि इसका उपयोग कैसे किया जाए।

+0

आप मेरे पास से अधिक प्राप्त कर चुके हैं। मुझे यह भी पता नहीं है कि जीएचसीआई की डीबगिंग सुविधाओं का उपयोग कैसे करें जब वे * उपलब्ध हैं- मुझे वास्तव में आरटीएफएम कभी-कभी करना चाहिए। आपके लिए एक सुझाव: जबकि segfaults 'unsafeCoerce' या' unsafePerformIO' के अनुचित उपयोग से परिणाम निश्चित कर सकते हैं, लेकिन उन्हें खराब असुरक्षित सरणी/वेक्टर संदर्भों से प्राप्त करना अधिक आम लगता है। क्या असुरक्षित ऑपरेशन का उपयोग आप सुरक्षित समकक्षों के साथ करते हैं, जैसे 'unsafeWrite' के विपरीत 'लिखना'? यदि ऐसा है, तो अपने परीक्षण के लिए सुरक्षित संस्करणों का उपयोग करके और फिर असुरक्षित लोगों को प्रदर्शन के लिए स्विच करने से चीज़ें * अधिक * आसान हो सकती हैं। – dfeuer

+1

@dfeuer: इस मामले में, जैसा कि मैंने आज खोजा था, segfault वास्तव में एक सूचक ("पीटीआर ए") को संदर्भित करने से आया था, जिसका अंतर्निहित स्मृति पहले ही सी पुस्तकालय (libSDL2) द्वारा मुक्त किया गया था, पैकेज का उपयोग कर रहा था। वह पूरी तरह से मेरी गलती थी। लेकिन सवाल अभी भी खड़ा है, क्योंकि मुझे डीबग का सहारा लेना पड़ा था। ट्रेस, और एक जटिल मामले में जो वास्तव में काफी समय ले सकता है। –

+0

बस यह सुनिश्चित करने के लिए - क्या आपने 'कैबल कॉन्फ़िगरेशन --ghc-option = -fPIC' या इसी तरह के साथ कॉन्फ़िगर किया था? एसडीएल 2 रीडमेम इसका उल्लेख करता है। – schellsan

उत्तर

0

स्टैक के लिए कुछ समर्थन है।stack ghci --load-local-deps $TARGET चल रहा है stack.yaml के packages फ़ील्ड में आपकी परियोजना और किसी भी निर्भरता को लोड करेगा, जिसमें उन्हें extra-dep एस के रूप में चिह्नित किया गया है। ब्रेकपॉइंट्स तब काम करेंगे। आप stack unpack $PACKAGE चलाकर packages पर stack.yaml में इसे जोड़कर जीएचसीआई में निर्भरता डीबग कर सकते हैं।

हालांकि यह एक पैनसिया नहीं है। यदि संकुल में विवादित पैकेज-वैश्विक भाषा एक्सटेंशन (या अन्य गतिशील झंडे) या मॉड्यूल नाम संघर्ष होते हैं तो यह काम नहीं करेगा। उदाहरण के लिए, यदि आपके शीर्ष-स्तरीय पैकेज में default-extensions: NoImplicitPrelude है और आपकी निर्भरता नहीं है, तो उनके पास एक प्रीलूड आयात नहीं होगा और लगभग निश्चित रूप से लोड नहीं होगा। this GHC bug देखें।

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