Rust कोड की डिबगिंग: «println!» से लेकर प्रोफेशनल टूल्स तक
\n\nहर कोई जिसने कम से कम एक सप्ताह Rust में कोड लिखा है, वह इस भावना को जानता है: कंपाइलर ने पास कर दिया, प्रोग्राम कंपाइल हो गया, चलता है… और कुछ पूरी तरह से अप्रत्याशित करता है। या बस एक रहस्यमय Segmentation fault के साथ क्रैश हो जाता है। डिबगिंग की दुनिया में आपका स्वागत है! अच्छी खबर: Rust में इसके लिए एक पूरा शस्त्रागार है - सरल मैक्रो से लेकर उन्नत डिबगर्स तक। इस लेख में हम Rust कोड की डिबगिंग के सभी तरीकों पर चर्चा करेंगे, बुनियादी से लेकर पेशेवर तक।
1. बुनियादी टूलकिट: dbg! और eprintln! मैक्रोज़
\n\nचलिए सबसे सरल और सुलभ से शुरू करते हैं। यदि आप Rust कोड लिख रहे हैं और जल्दी से समझना चाहते हैं कि वेरिएबल्स में क्या हो रहा है - तो dbg! का उपयोग करें। यह वेरिएबल का नाम, उसका मान, और फ़ाइल और लाइन नंबर दोनों प्रदर्शित करता है। पुराने println! की तुलना में कहीं अधिक सुविधाजनक।
fn calculate_even_sum(numbers: &[i32]) -> i32 {\n let mut sum = 0;\n for &n in numbers {\n if n % 2 == 0 {\n sum += n;\n dbg!(n, sum); // प्रत्येक सम संख्या और वर्तमान योग देखें\n }\n }\n sum\n}\n\nfn main() {\n let data = vec![1, 2, 3, 4, 5, 6];\n let result = calculate_even_sum(&data);\n dbg!(result);\n}\n\nइसे चलाएँ - और आप कुछ इस तरह देखेंगे:
\n\n[src/main.rs:6:13] n = 2\n[src/main.rs:6:13] sum = 2\n[src/main.rs:6:13] n = 4\n[src/main.rs:6:13] sum = 6\n[src/main.rs:6:13] n = 6\n[src/main.rs:6:13] sum = 12\n[src/main.rs:12:5] result = 12\n\nऔर यदि आपको stderr में लिखने की आवश्यकता है (उदाहरण के लिए, पाइप के दौरान stdout में बाधा न डालने के लिए) - तो eprintln! का उपयोग करें। प्रोडक्शन वातावरण में Rust कोड की डिबगिंग करते समय यह अपरिहार्य है।
2. log और env_logger के साथ उन्नत लॉगिंग
\n\nजब प्रोजेक्ट बड़ा हो जाता है, तो पूरे कोड में dbg! बिखेरना दर्दनाक हो जाता है। log और env_logger क्रेट्स बचाव में आते हैं। वे बिना पुनर्संकलन के लॉग को चालू/बंद करने की अनुमति देते हैं।
use log::{info, warn, error, debug};\n\nfn main() {\n env_logger::init();\n\n info!("प्रोग्राम शुरू हुआ");\n let x = 42;\n debug!("x का मान: {}", x);\n\n if x > 100 {\n warn!("x बहुत बड़ा है!");\n } else {\n error!("यह कोई त्रुटि नहीं है, बस एक जाँच है");\n }\n}\n\nइसे RUST_LOG=debug cargo run एनवायरनमेंट वेरिएबल के साथ चलाएँ - और आपको सभी लॉग मिलेंगे। केवल चेतावनियाँ चाहिए? RUST_LOG=warn। रीयल-टाइम में Rust एप्लिकेशन की डिबगिंग के लिए बहुत सुविधाजनक।
3. पैनिक और बैकट्रेस: एरर स्टैक पढ़ना
\n\nजब प्रोग्राम पैनिक करता है, तो Rust एक संदेश प्रदर्शित करता है। लेकिन अक्सर यह पर्याप्त नहीं होता। पूरा बैकट्रेस चालू करें:
\n\n$ RUST_BACKTRACE=1 cargo run\n\nया अधिकतम विवरण के लिए:
\n\n$ RUST_BACKTRACE=full cargo run\n\nआप पूरा कॉल स्टैक देखेंगे - पैनिक पॉइंट से main तक। यह Rust कोड की डिबगिंग करते समय महत्वपूर्ण है, यदि आप समझ नहीं पा रहे हैं कि त्रुटि कहाँ से आई।
उदाहरण: मान लीजिए, आपके पास ऐसा कोड है:
\n\nfn main() {\n let v = vec![1, 2, 3];\n println!("{}", v[10]); // पैनिक!\n}\n\nRUST_BACKTRACE=1 के साथ आप केवल "index out of bounds" नहीं, बल्कि सटीक लाइन और कॉल देखेंगे।
4. डिबग और ऑप्टिमाइज़ेशन मोड: debug बनाम release
\n\nएक महत्वपूर्ण बिंदु: debug मोड (डिफ़ॉल्ट) में Rust कोड की डिबगिंग पूरी जानकारी देती है। लेकिन release में कंपाइलर कोड को ऑप्टिमाइज़ करता है, और कुछ वेरिएबल गायब हो सकते हैं या क्रम बदल सकते हैं। यदि आप किसी "रिलीज़" बग को डीबग कर रहे हैं - तो डिबग जानकारी वाले प्रोफ़ाइल का उपयोग करें:
[profile.release]\ndebug = true\n\nCargo.toml में। यह आपको cargo run --release चलाने की अनुमति देगा