- Bun v1.1.5 ने
bun.reportक्रैश रिपोर्टर जोड़ा है, जो क्रैश या panic होने पर भी लगभग 150-बाइट के बिना निजी जानकारी वाले URL के ज़रिए Zig/C++ stack जानकारी भेजता है - मौजूदा OS crash reporters और core dumps में debug symbols·performance·privacy·executable size का बड़ा बोझ होता है, इसलिए इन्हें Bun जैसे CLI टूल पर लागू करना मुश्किल है
- नया तरीका ASLR की वजह से अस्पष्ट हुए addresses को module-relative addresses में बदलता है, और server commit SHA व platform के हिसाब से debug symbols से function names को restore करता है
- URL में platform, subcommand, commit SHA, feature flags, stack addresses, crash type और message शामिल होते हैं, और stack addresses को base64 VLQ से छोटा encode किया जाता है
- JavaScript/TypeScript source code या environment variables नहीं भेजे जाते; Bun टीम को diagnosis के लिए ज़रूरी Zig/C++ stack जानकारी और कुछ metadata ही भेजे जाते हैं
Bun ने अपना क्रैश रिपोर्टर क्यों बनाया
- लिखे जाने के समय Bun में 2,600 से अधिक खुले GitHub issues हैं, और कुछ issues को reproduce करना और debug करना खास तौर पर कठिन है
- Sentry जैसी crash reporting services apps और SaaS products के लिए उपयुक्त हैं, लेकिन Bun जैसे CLI टूल में core dumps upload करने पर privacy, performance और executable size की समस्याएँ बढ़ जाती हैं
- Bun v1.1.5 ने Zig और C++ crash reports के लिए एक छोटा नया format पेश किया है
- crash report लगभग 150-बाइट URL में समा जाती है
- इसमें निजी जानकारी शामिल नहीं होती
सिर्फ OS crash reporter से क्या कमी रह जाती है
- macOS जैसे कुछ operating systems में built-in crash reporter होता है, लेकिन उसका ठीक से उपयोग करने के लिए आमतौर पर application के साथ debug symbols भी distribute करने पड़ते हैं
- debug symbols, Bun distribution का आकार काफ़ी बढ़ा देते हैं
- Linux debug symbols लगभग 30MB
- macOS debug symbols लगभग 9MB
- Windows
.pdbfiles 250MB से अधिक
- Bun executable का एक उदाहरण
llvm-stripसे पहले और बाद में60Mसे51Mतक घटता है - debug symbols के बिना crash होने पर stack trace में सिर्फ
???और addresses बचते हैं, इसलिए उसका उपयोग सीमित रहता है - ASLR(Address space layout randomization) की वजह से function addresses में random offset मिल जाता है, इसलिए उन्हें उसी रूप में function names में restore नहीं किया जा सकता
bun.report कैसे काम करता है
- Bun v1.1.5 में crash या panic होने पर Bun, version, platform, execution arguments, memory usage, crash message के साथ
bun.reportलिंक प्रिंट करता है - जब उपयोगकर्ता लिंक खोलता है, तो उसे पहले से भरे हुए GitHub issue form पर redirect किया जाता है
- URL के अंदर remapped stack trace encode होकर रहती है
- server, URL में मौजूद जानकारी के आधार पर stack addresses को restore करता है और उन्हें Bun टीम के पढ़ने लायक crash report में बदल देता है
addresses को पढ़ने योग्य stack trace में बदलने की प्रक्रिया
- function address एक pointer होता है, जो memory में load हुए application code की location दिखाता है, और सुरक्षा कारणों से उसमें random offset शामिल होता है
- मूल विचार यह है कि raw address से binary का base address घटाकर relative address निकाला जाए
- वास्तविक implementation platform-specific API differences की वजह से अधिक जटिल है
- Windows में
GetModuleHandleExWके साथGET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESSflag का उपयोग किया जाता है, और module pointer को base address माना जाता है - Linux में
dl_iterate_phdrसे loaded modules को iterate किया जाता है, और जिस module में address आता है उसकेdl_phdr_info.dlpi_addrको base address के रूप में उपयोग किया जाता है - macOS में
_dyld_image_count,_dyld_get_image_headerसे modules को iterate किया जाता है और_dyld_get_image_vmaddr_slideसे ASLR slide लिया जाता है- macOS के result address में image offset बचा रहता है, जो Bun के मामले में
0x100000000है - URL को छोटा रखने के लिए इस offset को हटा दिया जाता है, लेकिन
llvm-symbolizerसे remap करने से पहले इसे फिर जोड़ना पड़ता है
- macOS के result address में image offset बचा रहता है, जो Bun के मामले में
- Windows में
- Linux और macOS में पहला module main application binary को दर्शाता है
- Windows में module name और
peb.ProcessParameters.ImagePathNameकी तुलना कर यह तय किया जा सकता है कि वह main binary है या नहीं - Bun local machine पर debug symbols download और parse नहीं करता, बल्कि demangling server को सौंपता है
- server debug symbols को cache कर सकता है
- stack trace को कुछ सेकंड में demangle किया जा सकता है
- और साथ ही यह नया GitHub issue खोलने वाले लिंक की भूमिका भी निभाता है
bun.report URL की संरचना
bun.reportURL में नीचे दी गई जानकारी encode होती है- Platform: platform को दिखाने वाला एक अक्षर। उदाहरण के लिए
wमतलब x86_64 Windows,Mमतलब aarch64 macOS - Subcommand:
bun test,bun install,bun runजैसे subcommand को दिखाने वाला एक अक्षर - Commit SHA: मौजूदा Bun version का commit SHA, जिसका बाद में debug symbols लाने में उपयोग होता है
- Feature Flags: crash से पहले इस्तेमाल किए गए APIs और features को दिखाने वाले संकेत
- Stack Trace Addresses: पिछले चरण में निकाले गए addresses
- Crash Type: crash प्रकार को दिखाने वाला एक अक्षर
- Crash Message: crash type के अनुसार अलग format में आने वाला message
- Platform: platform को दिखाने वाला एक अक्षर। उदाहरण के लिए
- URL में शामिल version number, वास्तविक processing से ज़्यादा इंसानों के पढ़ने के लिए होता है
- सिर्फ इस जानकारी से भी कुछ crash characteristics को हाथ से समझा जा सकता है
widentifier देखकर जल्दी समझा जा सकता है कि यह Windows crash है- string के अंत में
A2देखकर segmentation fault पहचाना जा सकता है
छोटे URL के लिए VLQ encoding
- stack trace addresses को URL छोटा रखने के लिए base64 Variable Length Quantity(VLQ) numbers के रूप में encode किया जाता है
- VLQ छोटे numbers को कम characters में व्यक्त कर सकता है, जबकि बड़े numbers को भी encode कर सकता है
- JavaScript source maps में line numbers store करने के लिए भी यही तकनीक उपयोग होती है
- server VLQ values को फिर relative addresses में decode करता है, commit hash और platform का उपयोग कर debug symbols download करता है, और फिर
llvm-symbolizerसे function names को demangle करता है - उदाहरण crash में यह सामने आता है कि assertion, Windows के module resolver code के एक हिस्से
dirInfoCachedMaybeLogमें fail हुआ था
feature flags encoding
- URL 64-bit integer भी encode करता है, और हर bit Bun की किसी खास feature के उपयोग से मेल खाती है
- ये flags यह संकेत देते हैं कि कौन-से APIs और systems ने crash को प्रभावित किया हो सकता है
.envfile auto-load होने परdotenvfeature set होता हैfetch()इस्तेमाल होने परfetchfeature set होता है
- Bun global variable container की मदद से feature usage track करता है, और हर API के अंदर संबंधित संख्या बढ़ाकर usage को mark करता है
- Zig के compile-time metaprogramming का उपयोग करके feature list को iterate किया जाता है और हर feature के लिए 1 bit इस्तेमाल करने वाला packed struct dynamic रूप से बनाया जाता है
inline forके उपयोग से compile time पर feature list iterate की जा सकती है, जबकि actual bit setting runtime पर की जाती है- मौजूदा
Featuresstruct में नया feature जोड़ने पर crash reporter में भी बिना दोहराव के उसका handling हो जाता है - यही तरीका C या Rust macros से भी संभव है, लेकिन Bun के implementation में Zig
comptimeको अधिक सरल और पढ़ने में आसान तरीके से इस्तेमाल किया गया है
core dump से अंतर
- core dumps में कहीं ज़्यादा जानकारी होती है, लेकिन उनका आकार बड़ा होता है, वे debug symbols के बिना कम उपयोगी होते हैं, और उनमें संवेदनशील या गोपनीय जानकारी काफ़ी अधिक शामिल हो सकती है
- Bun की नई reporting method, JavaScript/TypeScript source code, environment variables और दूसरी संवेदनशील जानकारी भेजे जाने की स्थिति से बचती है
- डिफ़ॉल्ट रूप से सब कुछ भेजने के बजाय, यह सिर्फ Zig/C++ stack trace और कुछ विवरण भेजती है, जिनकी समस्या के diagnosis में ज़रूरत होने की संभावना अधिक होती है
- अगर अतिरिक्त जानकारी चाहिए, तो उपयोगकर्ता से अलग से माँगी जा सकती है
- पहले की तरह सिर्फ unmapped addresses बचने की स्थिति की तुलना में, अब Bun टीम के लिए crash का diagnosis करना आसान हो जाता है
डेमो
- crash reporter को test करने के लिए एक छोटा web app bun.report पर उपलब्ध है
- किसी भी crash report URL के अंत में
/viewजोड़ने पर उस web app की screen पर जाया जा सकता है
1 टिप्पणियां
Hacker News की राय
अगर सामान्य stack trace के बजाय यह तरीका इस्तेमाल करने की वजह कई MB के debug symbols को वितरित करने से बचना है, तो लगता है कि उन्होंने बेहतर विकल्प—debug table में सिर्फ function names डालना—नज़रअंदाज़ कर दिया है
stack trace देखने के लिए web service इस्तेमाल करने से यह कहीं बेहतर तरीका है, और यह सिर्फ थ्योरी नहीं है; LLVM में पहले से लागू है: https://clang.llvm.org/docs/UsersManual.html#cmdoption-gline...
अगर एक URL से ज़रूरी चीज़ें लगभग अपने-आप भर जाती हैं, तो यह काफी आसान हो जाता है, और तभी developers वाकई crash reports डालते हैं। size भी महत्वपूर्ण था ताकि users के लिए कोई downside न बने, लेकिन मुख्य बात पूरे process को बहुत आसान बनाना है
इस use case में stack trace देखने के लिए web service की ज़रूरत होना कोई बड़ा नुकसान नहीं है। यह लगभग वैसा ही है जैसे frontend JavaScript bundle को obfuscate/minify करना, source map को Sentry पर upload करना, और फिर user browser से आए stack trace को Sentry में restore करके देखना। user वैसे भी वह stack trace नहीं देखने वाला, और मुझे भी Sentry से देखना असुविधाजनक नहीं लगता। वरना शायद मैं उसे देख ही नहीं पाता
alternative सुझाने के कई तरीके होते हैं
इन platforms पर बिना पूरे debug symbols के भी system libraries के function names symbolization के ज़रिए इसी तरह मिलते हैं
शानदार और बहुत creative है। अच्छा होगा अगर कई projects इस approach को अपनाएं। मूल बात executable/shared object के हिसाब से relative program counter के साथ stack trace छोड़ना है
मेरी जानकारी में Bun statically linked है, लेकिन dynamic linking system हो तो normalized program counter के आगे छोटे number के रूप में shared object ID लगानी होगी
उदाहरण के लिए Unreal Engine crash reporter कई सालों से ऐसा simple format भेज सकता है, और हर stack frame से काफी सटीक function/line number restore कर सकता है। हालांकि आम तौर पर minidump को अधिक पसंद किया जाता है, क्योंकि stack variables भी हों तो क्या हुआ था, इसके extra hints मिल जाते हैं
Microsoft ऐसे कामों में सच में बहुत अच्छा है। SQL Server में उन्होंने privacy हटाए हुए minidump इस्तेमाल किए थे, जो बहुत छोटे और बेहद उपयोगी थे
उस समय भी, 15 साल पहले, production SQL Server का full dump इतना विशाल file होता था कि उसे transfer करना मुश्किल था
Zig से जुड़े पहले tweet को देखने के बाद कई सालों तक Bun को follow करता रहा और हाल ही में इस्तेमाल करना शुरू किया; बिना किसी खास झंझट के बस ठीक से काम करता है
Bun काफी आकर्षक है। कुछ छोटे example projects में इस्तेमाल करके देखा; speed अच्छी है, और मुझे package management व JavaScript runtime को साथ जोड़ना पसंद आया
हालांकि ज्यादातर serious projects में मैं Dependabot इस्तेमाल कर रहा हूं। मेरी जानकारी में Dependabot का Bun support work in progress है, या कम-से-कम कुछ repository issues में discuss हो रहा है, इसलिए support release होने तक इस्तेमाल टाल रहा हूं
कोई regret नहीं है। जिन चीज़ों में speed बढ़ी है, उनसे मिलने वाली cumulative saving और developer experience में बड़ा सुधार उम्मीद के मुताबिक worth it है
बहुत लोग notice नहीं करेंगे कि ऐसी चीज़ों में कितना ध्यान दिया गया है। अच्छा है कि इससे दिखता है कि Bun team अपने craft की कितनी परवाह करती है
Bun शानदार है, लेकिन हाल में Fastify से HTTP/2 server बनाने की कोशिश की तो नहीं हो पाया
node:http2 createServer is not yet implemented in Bunerror आया, और message जिस issue की ओर इशारा करता है वह असल में HTTP/2 client support से जुड़ा है। client support v1.0.13 में पहले ही release हो चुका है: https://bun.sh/blog/bun-v1.0.13#http2-client-supportNotImplementedErrormessage को server-side issue की ओर point करने के लिए बदला जाना चाहिए: https://github.com/oven-sh/bun/issues/8823HTTP/2 server support top feature requests में से एक है: https://github.com/oven-sh/bun/issues?q=is%3Aissue+is%3Aopen...
यह feature आ जाए तो लगता है काफी ज़्यादा लोग Bun पर shift कर पाएंगे
Bun अभी अपने lifecycle में बहुत शुरुआती stage पर है। फिर भी project से काफी उम्मीद है
जानना चाहता हूं कि क्या सच में लोग Bun इस्तेमाल कर रहे हैं। क्या यह उम्मीद जितना अच्छा है?
TypeScript Node environment में ts-node, ts-jest, ESM support, top-level await आदि set up करना ज़रूरत से ज़्यादा झंझट भरा है। हाल के Node releases ने कुछ परेशानियां घटाई हैं, लेकिन यह
bun initजितना simple नहीं है। bun shell API भी मज़े से इस्तेमाल कर रहा हूं: https://bun.sh/blog/the-bun-shellerror messages भी Node से काफी खराब हैं। कुछ समय तक इस्तेमाल किया, लेकिन आजकल Node में
—loader tsxजोड़ दूं तो मेरी सारी ज़रूरतें पूरी हो जाती हैं और downsides भी नहीं हैं। simple server, जैसे WebSocket इस्तेमाल करता हो और आपको पक्का हो कि native modules की ज़रूरत नहीं पड़ेगी, तो Bun consider करने लायक है। ऐसी कुछ services सच में चला रहा हूंinstant startup speed अभी भी हैरान करती है
अभी कुछ चीज़ें missing हैं, लेकिन मेरे लिए यह पहले ही Node से बेहतर है
यह article Zig case study के तौर पर भी बहुत अच्छा लगता है। दिलचस्प है
Bun को REPL इस्तेमाल करने से पहले 37 packages download करने पड़ते हैं। internet न हो तो REPL भी नहीं चलता
bun replचलाने परbun-replpackage manifest download fail होने का error आता है। यह कोई बड़ा issue नहीं है, लेकिन मेरी उम्मीद थी कि single executable को PATH में डालते ही बिना installation के तुरंत काम करेगा, और इसे लेकर काफी उत्साहित थाinternally
bun repl,bunx bun-replजैसा ही काम करता है