3 पॉइंट द्वारा GN⁺ 2024-06-10 | 2 टिप्पणियां | WhatsApp पर शेयर करें
  • libtree एक ऐसा टूल है जो ldd के आउटपुट को ट्री में बदलता है और यह समझाता है कि shared library कैसे खोजी गई, या वह क्यों नहीं मिल रही है
  • डिफ़ॉल्ट आउटपुट में कुछ standard dependencies छिपी रहती हैं, और -v, -vv, -vvv के साथ छिपी हुई लाइब्रेरियाँ तथा पहले से मिल चुकी लाइब्रेरियों की dependencies को चरणबद्ध तरीके से देखा जा सकता है
  • --path या -p soname की जगह path दिखाता है, और --max-depth से recursive खोज की गहराई सीमित की जा सकती है
  • इंस्टॉलेशन v3.1.1 prebuilt binaries, Fedora/RHEL/CentOS, Ubuntu 22.04+, और GNU Guix के ज़रिए किया जा सकता है
  • source build के लिए C99 समझने वाला C compiler चाहिए, और make इस्तेमाल करते समय LDFLAGS=-static की सिफारिश की जाती है

libtree क्या करता है

  • libtree एक टूल है जो ldd को ट्री के रूप में बदलता है
  • यह समझाता है कि shared library कैसे खोजी जाती है, या उसका location क्यों नहीं मिल पाता
  • README में doc/screenshot.png का screenshot शामिल है

आउटपुट विकल्प

  • डिफ़ॉल्ट आउटपुट में कुछ standard dependencies दिखाई नहीं जातीं
  • अधिक विस्तृत आउटपुट verbosity options से नियंत्रित होता है
    • libtree -v: वे लाइब्रेरियाँ दिखाता है जिन्हें डिफ़ॉल्ट रूप से छोड़ दिया जाता है
    • libtree -vv: डिफ़ॉल्ट रूप से छोड़ी जाने वाली लाइब्रेरियों की dependencies भी दिखाता है
    • libtree -vvv: पहले से मिल चुकी लाइब्रेरियों की dependencies भी दिखाता है
  • --path या -p फ्लैग soname की जगह path दिखाता है
    • उदाहरण: libtree -p $(which tar)
  • --max-depth recursive depth को सीमित करता है

इंस्टॉल करने का तरीका

  • Prebuilt binaries for v3.1.1: Linux के लिए prebuilt binaries उपलब्ध हैं
  • Fedora / RHEL / CentOS में dnf से इंस्टॉल करें
    • RHEL और उससे निकले distributions में पहले epel-release को सक्षम करें
    • dnf install libtree-ldd
  • Ubuntu 22.04+ में apt-get install libtree से इंस्टॉल करें
  • GNU Guix में guix install libtree से इंस्टॉल करें
  • Older release v2.0.0 भी उपलब्ध है

source से build करना

  • libtree के लिए C99 समझने वाला C compiler चाहिए
  • बेसिक build प्रक्रिया में repository clone करने के बाद make चलाया जाता है
  • make इस्तेमाल करते समय LDFLAGS=-static की सिफारिश की जाती है
  • README में curl से libtree.c डाउनलोड करके compile करने वाला unsafe quick install कमांड भी अलग fold section में दिया गया है

2 टिप्पणियां

 
GN⁺ 2024-06-10
Hacker News की राय
  • क्या यह टूल भी ldd के उस अनपेक्षित व्यवहार को वैसे ही अपनाता है, जिसमें वह जांची जा रही लाइब्रेरी के कुछ हिस्सों को सचमुच execute कर देता है?
    https://catonmat.net/ldd-arbitrary-code-execution

    • हाल के, लगभग 5 साल से नए ldd versions target binary को execute नहीं करते
      संदर्भ: https://manpages.debian.org/unstable/manpages/ldd.1.en.html#...
    • मोबाइल पर code को जल्दी से देखने पर लगता है कि यह ऐसा नहीं करता
      असल में यह ELF file को सीधे parse करता है, और dependencies को भी recursively parse करता दिखता है, इसलिए काफी बढ़िया है
    • मैंने Python के लिए धुंधले तौर पर कुछ ऐसा ही बनाया था, लेकिन इस समस्या को आखिर तक workaround नहीं कर पाया https://github.com/google/importlab/issues/69
    • objdump इस्तेमाल करने पर ELF file में encoded data जैसा है वैसा output कर देता है
      इसमें vdso द्वारा खोजी जाने वाली libraries की सूची भी शामिल होती है
  • ऐसा ही एक टूल lddtree भी है
    https://github.com/gentoo/pax-utils/tree/master

  • ldd से छूटी हुई dependency को recursively बार-बार trace करना काफी उबाऊ होता है
    इसलिए यह अच्छा सुधार लगता है, और अगली बार कोई अस्पष्ट not found मिले तो मैं इसे आजमाऊंगा

  • मूल रूप से यह Linux CLI version का depends.exe जैसा है

    • वह खास टूल अब नए Windows versions पर ठीक से काम नहीं करता
      इसके बजाय https://github.com/lucasg/Dependencies इस्तेमाल करना बेहतर है। यह भी पूरी तरह up-to-date नहीं है, लेकिन…
      अगर आपने Visual Studio install किया है और installer में x64/x86 build tools (latest) चुना है, तो VS Developer Command Prompt में dumpbin /dependents चलाना अब भी सबसे भरोसेमंद विकल्प है
    • हां, मैंने भी बिल्कुल यही सोचा था
      [1] https://www.dependencywalker.com/
  • जो लोग जानना चाहते हैं कि colors का क्या मतलब है, उनके लिए लिख देता हूं; manpage/README में मुझे नहीं मिला
    मैजेंटा: exclude list में है, सिर्फ -v[v[v]] में दिखता है
    नीला: पहले देखा जा चुका item है, इसलिए कई बार आने वाली dependency पहचानी जा सकती है

  • “लाइब्रेरी क्यों मिलती है या नहीं मिलती” का मतलब क्या है? या तो वह LD_LIBRARY_PATH में होती है या नहीं होती, बस यही नहीं?
    screenshot देखकर समझ नहीं आ रहा कि यह किस ओर इशारा कर रहा है

    • इस टूल के context में ठीक-ठीक नहीं जानता, लेकिन library search एक single environment variable से कहीं ज्यादा जटिल है
      system search paths, runpath, rpath, LD_LIBRARY_PATH आदि अलग-अलग directory search methods होते हैं
      libraries आम तौर पर foo.so जैसे छोटे नाम से link होती हैं, लेकिन library के full path से भी dynamic link हो सकती हैं
      साथ ही, सामान्य तौर पर LD_LIBRARY_PATH setting से बच सकें तो बचना बेहतर है। हमेशा संभव नहीं होता, लेकिन set करने पर यह हर execution में search priority में सबसे ऊपर आ जाती है। भले ही कोई चीज library के full path से dynamically linked हो, LD_LIBRARY_PATH priority ले लेता है और search method को पूरी तरह flat बना देता है
    • library के मिलने के लिए उसका LD_LIBRARY_PATH के अंदर होना जरूरी नहीं है
      title का मुद्दा यह है कि libtree executable से सभी direct और indirect dependencies तक जाने वाला path आसानी से खोजने देता है। इसका एक use missing dependency की समस्या समझने में मदद करना है
      असल में अगर आप package system इस्तेमाल कर रहे हैं, तो dependency missing होना बहुत आम नहीं होगा, इसलिए libtree का इस्तेमाल शायद किसी और वजह से होगा
    • बात सिर्फ LD_LIBRARY_PATH में होने या न होने की नहीं है; हर library के लिए load time पर evaluate होने वाला RPATH भी होता है
      बड़ा point यह है कि dependencies एक graph बनाती हैं, और इसे tree की तरह दिखाया जा सकता है। यह जानना उपयोगी है कि किस library की जरूरत वाली कौन-सी library के कारण कोई खास library नहीं मिल रही
    • libraries सिर्फ LD_LIBRARY_PATH से नहीं मिलतीं। loader library खोजने के लिए कई अलग-अलग sources भी consider करता है
      normal setup में यह load हो रही हर binary के सामान्य ELF fields और loader को पता अन्य paths का combination होता है
      ऐसी systems में जहां same library के कई versions या same name की कई libraries हों, LD_LIBRARY_PATH पर निर्भर रहना बहुत short-sighted हो सकता है। loader हर binary के लिए LD_LIBRARY_PATH के paths को क्रम से search करता है और पहली matching library चुनता है। अगर आपने किसी और तरीके से higher-priority path set नहीं किया है, तो वह library असल में वही न भी हो सकती है जो आप चाहते हैं, और runtime पर unexpected errors हो सकते हैं
      बेहतर तरीका यह है कि उस binary को जिन libraries की जरूरत है, जहां वे मौजूद हैं, वहां के लिए RPATH set किया जाए
      अगर environment और RPATH settings consistent नहीं हैं, तो same library के कई versions साथ-साथ load हो सकते हैं। यह टूल यह समझने में मदद करता है कि समस्या है या नहीं, और क्यों
    • कम से कम RPATH, RUNPATH, LD_LIBRARY_PATH तो हैं
      यह टूल ldd based है, इसलिए शायद DYLD_LIBRARY_PATH, DYLD_FALLBACK_FRAMEWORK_PATH, DYLD_FALLBACK_LIBRARY_PATH, @executable_path, @loader_path, @rpath भी interpret करेगा
  • सच में उपयोगी है। आम तौर पर असली requirements क्या हैं यह जानने के लिए मैं readelf से sections पढ़ता हूं

  • क्या LD_DEBUG=libs काफी नहीं है?

    • वह library dependencies का static evaluation नहीं, बल्कि loader debug flag है, इसलिए बिल्कुल same नहीं है
  • पता नहीं यह bug है या नहीं, लेकिन vim example में ldd और libtree अलग-अलग libraries दिखाते हैं
    उदाहरण के लिए linux-vdso.so.1 ldd में list के सबसे ऊपर आता है, लेकिन libtree में बिल्कुल नहीं दिखता

    • linux-vdso.so.1 कोई actual library नहीं है जिसे file system में कहीं खोजा जा सके, और ELF file के अंदर भी इसका reference नहीं होता, इसलिए libtree इसे नहीं जान सकता
      इसके बजाय kernel newly started process के address space में इसे automatically map करता है। यह gettimeofday जैसे functions में system call overhead से बचने के लिए optimization है। संदर्भ: https://man7.org/linux/man-pages/man7/vdso.7.html
  • NixOS पर closed-source binary चलाने के लिए क्या include करना है यह पता लगाने के लिए मैंने कभी ldd को recursively चलाने वाली एक गड़बड़-सी छोटी script बनाई थी
    अगर फिर कभी ऐसा करना पड़ा, तो इस टूल को एक बार आजमाऊंगा

 
kayws426 2024-06-11

अच्छा लग रहा है!!