একক হোস্টে একাধিক গ্লিবসি লাইব্রেরি


171

একক হোস্টে একাধিক গ্লিবসি লাইব্রেরি

আমার লিনাক্স (SLES-8) সার্ভারটিতে বর্তমানে গ্লিবসি-২.২.৫-২৩৫ রয়েছে, তবে আমার একটি প্রোগ্রাম রয়েছে যা এই সংস্করণে কাজ করবে না এবং এটির জন্য গ্লিবসি -২.৩.৩ প্রয়োজন।

একই হোস্টে একাধিক গ্লিবসি ইনস্টল করা কি সম্ভব?

পুরানো গ্লিবসিতে আমার প্রোগ্রামটি চালানোর সময় আমি এই ত্রুটিটি পেয়েছি:

./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./myapp)
./myapp: /lib/i686/libpthread.so.0: version `GLIBC_2.3.2' not found (required by ./myapp)
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libxerces-c.so.27)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)
./myapp: /lib/i686/libc.so.6: version `GLIBC_2.3' not found (required by ./libstdc++.so.6)

সুতরাং আমি newglibc নামে একটি নতুন ডিরেক্টরি তৈরি করেছি এবং নিম্নলিখিত ফাইলগুলি এখানে অনুলিপি করেছি:

libpthread.so.0
libm.so.6
libc.so.6
ld-2.3.3.so
ld-linux.so.2 -> ld-2.3.3.so

এবং

export LD_LIBRARY_PATH=newglibc:$LD_LIBRARY_PATH

তবে আমি একটি ত্রুটি পেয়েছি:

./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libpthread.so.0)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by libstdc++.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libm.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_2.3' not found (required by ./newglibc/libc.so.6)
./myapp: /lib/ld-linux.so.2: version `GLIBC_PRIVATE' not found (required by ./newglibc/libc.so.6)

সুতরাং দেখা যাচ্ছে যে তারা এখনও / লিবিতে লিঙ্ক করছে এবং আমি যেখানে রেখেছি সেখান থেকে তারা তুলছে না?

ধন্যবাদ


1
SLES-11 সার্ভারের সাথে একই সমস্যা। আপডেট করতে পারে না এবং সাম্প্রতিক স্টাফগুলির প্রয়োজন। ওহ আমার ...
উমনিয়োব

FWIW, export LD_LIBRARY_PATH=newglibc:$LD_LIBRARY_PATH করেনি আমার জন্য সমস্যা সমাধানের! এটি অবশ্যই 'সবার জন্য কাজ করবে না, তবে এটি যদি কাজ করে তবে এটি একটি সহজ সমাধান! ধন্যবাদ! :)
রিনোগো

উত্তর:


229

একই সিস্টেমে একাধিক সংস্করণ glibc পাওয়া খুব সম্ভব (আমরা এটি প্রতিদিন করি)।

তবে আপনার জানা দরকার যে গ্লিবসি অনেকগুলি টুকরো (200+ শেয়ার করা লাইব্রেরি) নিয়ে গঠিত যা অবশ্যই মিলবে must টুকরোগুলির মধ্যে একটি হ'ল ld-linux.so.2, এবং এটি অবশ্যই libc.so.6 এর সাথে মেলে, বা আপনি যে ত্রুটিগুলি দেখছেন তা দেখতে পাবেন।

Ld-linux.so.2 এর পরম পাথটি লিংক সময় কার্যকরভাবে কার্যকর করা যায় এবং লিংকটি সম্পন্ন হওয়ার পরে সহজে পরিবর্তন করা যায় না।

এক্সিকিউটেবল তৈরি করতে যা নতুন গ্লিবিকের সাথে কাজ করবে, এটি করুন:

g++ main.o -o myapp ... \
   -Wl,--rpath=/path/to/newglibc \
   -Wl,--dynamic-linker=/path/to/newglibc/ld-linux.so.2

-rpathLinker বিকল্প লাইব্রেরির জন্য রানটাইম লোডার অনুসন্ধান করতে হবে /path/to/newglibc(যদি আপনি সেট হতো না তাই LD_LIBRARY_PATHএটা চালানোর আগে), এবং -dynamic-linkerবিকল্প "সেকা" সঠিক পাথ হবে ld-linux.so.2আবেদন মধ্যে।

আপনি যদি myappঅ্যাপ্লিকেশনটিকে রিলিঙ্ক করতে না পারেন (যেমন এটি একটি তৃতীয় পক্ষের বাইনারি), সমস্ত হারিয়ে যায় না, তবে এটি আরও জটিল হয়। একটি সমাধান এর জন্য উপযুক্ত chrootপরিবেশ নির্ধারণ করা। আর একটি সম্ভাবনা হল rtldi এবং একটি বাইনারি সম্পাদক ব্যবহার করা ।


3
নোট করুন -Wl,--dynamic-linker=file(ELF এক্সিকিউটেবলের জন্য সংকলন করার সময় (দুটি '-' লাগে) কেবল তখনই কাজ করে। চেক/sbin/ldconfig -p | grep ld
টম

49
এখন আপনি একটি সুবিধাজনক ইউটিলিটি patchelf( nixos.org/patchelf.html ) ব্যবহার করতে পারেন , যা আপনাকে ইতিমধ্যে সংকলিত ইএলএফ এর আরপিথ এবং দোভাষীকে সংশোধন করতে দেয়।
মাইকেল পানকভ

10
এটি উল্লেখ করার মতো যে -Wl,--rpathপরিবর্তনের পরিবর্তে নতুন গ্লিব্যাক ব্যবহার করে পাথ নির্দিষ্ট করা LD_LIBRARY_PATHসুবিধা ছাড়া অন্য কারণগুলির জন্য গুরুত্বপূর্ণ হতে পারে: যদি প্রোগ্রামটি শিশু প্রসেসগুলি চালু করে LD_LIBRARY_PATHতবে সাধারণত তাদের মান উত্তরাধিকার সূত্রে প্রাপ্ত হবে, তবে তারা যদি ব্যবহারের জন্য সংকলিত না হয় তবে নতুন গ্লিবসি (উদাহরণস্বরূপ, তারা যদি স্টক বাইনারি পছন্দ করে bash) তবে তারা আরম্ভ করবে না।
হাইকম্যান্ডার

13
অন্য বিকল্পটি নতুন ld.so সরাসরি চলছে, এটি আপনার বাইনারি প্রোগ্রামটিকে প্যারামিটার হিসাবে পাস করছে; এটি কার্যকরভাবে ld.so ব্যবহার করে ডাব্লু / ও প্রোগ্রামটি পুনরায় /path/to/newglibc/ld-linux.so.2 --library-path /path/tonewglibc/lib64:/path/to/newglibc/usr/lib64 /path/to/myapp
সংকলনের


67

এই প্রশ্নটি পুরানো, অন্য উত্তরগুলি পুরানো। "নিযুক্ত রাশিয়ান" এর উত্তরটি খুব ভাল এবং তথ্যবহুল, তবে আপনার যদি সোর্স কোড থাকে তবে এটি কার্যকর হয়। যদি আপনি না করেন তবে বিকল্পগুলি ফিরে আসার সময় খুব জটিল ছিল। ভাগ্যক্রমে আজকাল প্যাচেলফ ব্যবহার করে আমাদের কাছে এই সমস্যার একটি সহজ সমাধান রয়েছে (যেমনটি তাঁর একটি জবাবে মন্তব্য করা হয়েছে) । আপনাকে যা করতে হবে তা হ'ল:

$ ./patchelf --set-interpreter /path/to/newglibc/ld-linux.so.2 --set-rpath /path/to/newglibc/ myapp

এবং তারপরে, আপনি কেবল আপনার ফাইলটি কার্যকর করতে পারেন:

$ ./myapp

chrootধন্যবাদ বা ম্যানুয়ালি বাইনারি সম্পাদনা করার দরকার নেই , ধন্যবাদ। তবে মনে রাখবেন যে আপনার বাইনারিটি প্যাচ করার আগে ব্যাকআপ করবেন, যদি আপনি নিশ্চিত হন না যে আপনি কী করছেন, কারণ এটি আপনার বাইনারি ফাইলটি পরিবর্তন করে। আপনি এটি প্যাচ করার পরে, আপনি দোভাষী / আরপথে পুরানো পথটি পুনরুদ্ধার করতে পারবেন না। যদি এটি কাজ করে না, আপনি যতক্ষণ না প্রকৃতপক্ষে কাজ করবে এমন পথ না পাওয়া পর্যন্ত আপনাকে এটি প্যাচিং চালিয়ে যেতে হবে ... ঠিক আছে, এটি একটি ট্রায়াল-অ্যান্ড-ত্রুটি প্রক্রিয়া হওয়ার দরকার নেই। উদাহরণস্বরূপ, ওপি-র উদাহরণে তার দরকার ছিল GLIBC_2.3, যাতে আপনি সহজেই আবিষ্কার করতে পারেন যে কোন লিব ব্যবহার করে সেই সংস্করণটি সরবরাহ করে strings:

$ strings /lib/i686/libc.so.6 | grep GLIBC_2.3
$ strings /path/to/newglib/libc.so.6 | grep GLIBC_2.3

তত্ত্ব অনুসারে, প্রথম গ্রেপটি খালি আসবে কারণ সিস্টেম লাইবসিটিতে তার পছন্দ মতো সংস্করণ নেই, এবং ২ য়টির GLIBC_2.3 আউটপুট করা উচিত কারণ এটির সংস্করণটি myappব্যবহার করা হচ্ছে, তাই আমরা জানি আমরা patchelfসেই পথটি ব্যবহার করে আমাদের বাইনারি করতে পারি ।

আপনি যখন লিনাক্সে বাইনারি চালানোর চেষ্টা করেন, বাইনারি লিঙ্কারটি লোড করার চেষ্টা করে, তারপরে গ্রন্থাগারগুলি এবং সেগুলি সমস্ত পথে এবং / অথবা সঠিক জায়গায় হওয়া উচিত। যদি আপনার সমস্যা লিঙ্কারের সাথে থাকে এবং আপনি কীভাবে আপনার বাইনারিটি কোন পথটি সন্ধান করছেন তা জানতে চান, আপনি এই আদেশটি দিয়ে খুঁজে পেতে পারেন:

$ readelf -l myapp | grep interpreter
  [Requesting program interpreter: /lib/ld-linux.so.2]                                                                                                                                                                                   

যদি আপনার সমস্যাটি লিবসের সাথে থাকে তবে কমান্ডগুলি আপনাকে প্রদত্ত লিবগুলি দেবে:

$ readelf -d myapp | grep Shared
$ ldd myapp 

এটি আপনার বাইনারিগুলির প্রয়োজনীয় libs তালিকাভুক্ত করবে, তবে আপনি সম্ভবত সমস্যাগুলি সম্পর্কে জানেন, যেহেতু তারা ইতিমধ্যে ওপির ক্ষেত্রে যেমন ত্রুটি উপস্থাপন করছেন।

"প্যাচেলফ" এই 2 টি সমস্যা সম্পর্কিত কোনও প্রোগ্রাম চালানোর চেষ্টা করার সময় আপনি যে বিভিন্ন সমস্যার মুখোমুখি হতে পারেন তার জন্য কাজ করে। উদাহরণস্বরূপ, আপনি যদি পান ELF file OS ABI invalid:, --set-interpreterআমি এখানে এখানে বর্ণনা হিসাবে এটি একটি নতুন লোডার ( কমান্ডের অংশ) সেট করে ঠিক করা যেতে পারে । আর একটি উদাহরণ পাওয়ার সমস্যাটিNo such file or directory যেমন exemplified, যখন আপনি একটি ফাইল আছে এবং এক্সিকিউটেবল হয় চালানো এখানে । সেই বিশেষ ক্ষেত্রে, ওপি লোডারটির একটি লিঙ্ক মিস করছিল তবে সম্ভবত আপনার ক্ষেত্রে আপনার রুট অ্যাক্সেস নেই এবং লিঙ্কটি তৈরি করতে পারবেন না। নতুন দোভাষী স্থাপন করা আপনার সমস্যার সমাধান করবে।

অন্তর্দৃষ্টি এবং সমাধানের জন্য নিয়োগকৃত রাশিয়ান এবং মাইকেল পানকভকে ধন্যবাদ!


1
এটি ছিল সবচেয়ে সহায়ক! আমি টেনস্রোফ্লোয়ের জন্য নতুন গ্লিবিসি ব্যবহার করার জন্য পাইথনের বাইনারি টানলাম
ফাইজান

এটি একটি ঝরঝরে সমাধান (আমি আগে সম্পর্কে জানতাম না patchelf), তবে "বাইনারি সম্পাদনা করার দরকার নেই" এই উক্তিটি কিছুটা বিভ্রান্তিকর হতে পারে (যেহেতু আপনি আসলে আপনার বাইনারিগুলি সম্পাদনা করছেন)।
larsks

সেখানে, স্থির। ;)
এমএসবি

সত্যিই সহায়ক ইউটিলিটি! ধন্যবাদ! যদিও আমি কেবলমাত্র নির্ভরশীলতাগুলি সমাধান করার কয়েক ঘন্টা পরে বিভাগের ত্রুটি অর্জন করতে সক্ষম হয়েছি এবং স্থানীয়ভাবে ক্রম কোনও অ্যাডমিন সুবিধা ছাড়াই ইনস্টল করার জন্য সমস্ত কিছু প্যাচিং করছি ...
জি বার্গারন

@ fgiraldeau প্রশংসা করার জন্য ধন্যবাদ। :) তবে প্রশ্নটি জিজ্ঞাসা করা হয়েছিল, উত্তর দেওয়া হয়েছিল এবং 2009 সালে গৃহীত হয়েছিল, আমি উত্তরটি গ্রহণের আগে কেউ 8 বছর অপেক্ষা করবে বলে আশা করবো না। heheh; ডি
এমএসবি

20

LD_PRELOAD ব্যবহার করুন: আপনার লাইব্রেরিটিকে ম্যান লিব ডিরেক্টরি থেকে বাইরে কোথাও রেখে দিন:

LD_PRELOAD='mylibc.so anotherlib.so' program

দেখুন: উইকিপিডিয়া নিবন্ধ


1
একটি জটিল মেকফিলের জন্য এটি দুর্দান্ত কাজ হিসাবে ভেবেছিল তবে এটি আমার পক্ষে কার্যকর হয়নি
গ্যালাকটিকা

এটি বিশেষত দরকারী যারা কোনও উত্স বাইনারি.থ্যাঙ্কস
কোডার

2
উম ... আমি ভুল ছিলাম, মনে হচ্ছে lp-linux.so এর / পথ / to / new / lib / frist দরকার আছে যখন উত্স সংকলন এবং লিঙ্ক করা হচ্ছে
কোডার

1
Ld - #। ##। এর ফলে এটি কাজ করে না (সুতরাং আপনার সিস্টেমে glibc lib থেকে) libc.so এর মতো একই গ্লিবিক সংস্করণ নয় # # (আপনার বিকল্প গ্লাবসি লিবি থেকে)
অ্যান্ডি

12

প্রথমত, প্রতিটি গতিশীলভাবে সংযুক্ত প্রোগ্রামের সবচেয়ে গুরুত্বপূর্ণ নির্ভরতা হ'ল লিংক। সমস্ত লাইব্রেরি অবশ্যই লিঙ্কারের সংস্করণের সাথে মেলে।

আসুন সরল এক্সপেলটি নেওয়া যাক: আমার কাছে নতুন সেট উবুন্টু সিস্টেম রয়েছে যেখানে আমি কিছু প্রোগ্রাম পরিচালনা করি (আমার ক্ষেত্রে এটি ডি সংকলক - ldc2)। আমি এটি পুরানো সেন্টোজে চালাতে চাই, তবে পুরানো গ্লিবসি লাইব্রেরির কারণে এটি অসম্ভব। আমি পেয়েছি

ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.15' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)
ldc2-1.5.0-linux-x86_64/bin/ldc2: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by ldc2-1.5.0-linux-x86_64/bin/ldc2)

আমাকে উবুন্টু থেকে সেন্টোতে সমস্ত নির্ভরতা অনুলিপি করতে হবে। সঠিক পদ্ধতিটি নিম্নলিখিত:

প্রথমে সমস্ত নির্ভরতা যাচাই করা যাক:

ldd ldc2-1.5.0-linux-x86_64/bin/ldc2 
    linux-vdso.so.1 =>  (0x00007ffebad3f000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f965f597000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f965f378000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f965f15b000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f965ef57000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f965ec01000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f965e9ea000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f965e60a000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f965f79f000)

linux-vdso.so.1 একটি সত্যিকারের গ্রন্থাগার নয় এবং আমাদের এটির যত্ন নেওয়ার দরকার নেই।

/lib64/ld-linux-x86-64.so.2 লিঙ্কার, যা লিনাক্স ব্যবহার করে সমস্ত গতিশীল লাইব্রেরির সাথে এক্সিকিউটেবলের লিঙ্ক করে।

বাকি ফাইলগুলি সত্যিকারের লাইব্রেরি এবং সেগুলির সবগুলি লিঙ্কারের সাথে একসাথে সেন্টোসের কোথাও অনুলিপি করা উচিত।

আসুন ধরে নেওয়া যাক সমস্ত লাইব্রেরি এবং লিঙ্কার "/ মাইলিবস" ডিরেক্টরিতে রয়েছে।

ld-linux-x86-64.so.2 - আমি ইতিমধ্যে বলেছি - লিঙ্কার er এটি ডায়নামিক লাইব্রেরি নয় স্ট্যাটিক এক্সিকিউটেবল। আপনি এটি চালাতে পারেন এবং দেখতে পারেন এটির কিছু প্যারামিটার রয়েছে, যেমন - লাইবারি-পাথ (আমি এটিতে ফিরে আসব)।

লিনাক্সে, গতিশীলভাবে সংযুক্ত প্রোগ্রামটি কেবল তার নাম দ্বারা লঞ্চ করা যেতে পারে, যেমন

/bin/ldc2

লিনাক্স এই জাতীয় প্রোগ্রামটি র‍্যামে লোড করে এবং এর জন্য কোন লিঙ্কার সেট করা আছে তা পরীক্ষা করে। সাধারণত, -৪-বিট সিস্টেমে এটি /lib64/ld-linux-x86-64.so.2 হয় (আপনার ফাইল সিস্টেমে এটি বাস্তব এক্সিকিউটেবলের প্রতীকী লিঙ্ক)। তারপরে লিনাক্স লিঙ্কার চালায় এবং এটি গতিশীল লাইব্রেরি লোড করে।

আপনি এটিকেও সামান্য পরিবর্তন করতে পারেন এবং এ জাতীয় কৌশল করতে পারেন:

/mylibs/ld-linux-x86-64.so.2 /bin/ldc2

এটি লিনাক্সকে নির্দিষ্ট লিঙ্কার ব্যবহার করতে বাধ্য করার জন্য পদ্ধতি।

এবং এখন আমরা উল্লিখিত পূর্ববর্তী প্যারামিটার - লাইব্রেরি-পথে ফিরে যেতে পারি

/mylibs/ld-linux-x86-64.so.2 --library-path /mylibs /bin/ldc2

এটি ldc2 চালাবে এবং / mylibs থেকে ডায়নামিক লাইব্রেরি লোড করবে।

এই পদ্ধতিটি চয়নকারী (সিস্টেম ডিফল্ট নয়) লাইব্রেরি সহ এক্সিকিউটেবল কল করার পদ্ধতি।


আমি আরএইচ 7 এ একটি প্রোগ্রাম সংকলন করেছি এবং এটি আরএইচ 6 এ চালানোর প্রয়োজন। আমি কোনও নতুন নির্বাহযোগ্য বা প্যাচেলফ ব্যবহার করতে চাইনি, সুতরাং এটি একটি দুর্দান্ত বিকল্প।
রাজকোক

9

সেটআপ 1: উত্সর্গীকৃত জিসিসি ছাড়াই আপনার নিজের গ্লিবসি সংকলন করুন এবং এটি ব্যবহার করুন

এই সেটআপটি কার্যকর হতে পারে এবং দ্রুত হয় কারণ এটি পুরো গিসি সরঞ্জাম সরঞ্জামটি পুনরায় সংশ্লেষ করে না, কেবল গ্লিবসি।

কিন্তু এটা নির্ভরযোগ্য হিসাবে এটি ব্যবহার করে হোস্ট সি রানটাইম যেমন বস্তু হিসেবে নয় crt1.o, crti.oএবং crtn.oজন্য glibc দ্বারা উপলব্ধ। এটিতে এখানে উল্লেখ করা হয়েছে: https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21# কমপাইল_গেইনস্ট_গ্লিবসি_ইন_আইনস্টিন_লোকেশন এই বিষয়গুলি প্রাথমিকভাবে সেটআপ করে যা গ্লিবসি নির্ভর করে, তাই আমি বিস্মিত হবো না যদি জিনিসগুলি বিস্ময়করভাবে ক্র্যাশ হয়ে যায় I এবং দুর্দান্তভাবে সূক্ষ্ম উপায়।

আরও নির্ভরযোগ্য সেটআপের জন্য, নীচে সেটআপ 2 দেখুন।

গ্লিবসি তৈরি করুন এবং স্থানীয়ভাবে ইনস্টল করুন:

export glibc_install="$(pwd)/glibc/build/install"

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28
mkdir build
cd build
../configure --prefix "$glibc_install"
make -j `nproc`
make install -j `nproc`

সেটআপ 1: বিল্ডটি যাচাই করুন

test_glibc.c

#define _GNU_SOURCE
#include <assert.h>
#include <gnu/libc-version.h>
#include <stdatomic.h>
#include <stdio.h>
#include <threads.h>

atomic_int acnt;
int cnt;

int f(void* thr_data) {
    for(int n = 0; n < 1000; ++n) {
        ++cnt;
        ++acnt;
    }
    return 0;
}

int main(int argc, char **argv) {
    /* Basic library version check. */
    printf("gnu_get_libc_version() = %s\n", gnu_get_libc_version());

    /* Exercise thrd_create from -pthread,
     * which is not present in glibc 2.27 in Ubuntu 18.04.
     * /programming/56810/how-do-i-start-threads-in-plain-c/52453291#52453291 */
    thrd_t thr[10];
    for(int n = 0; n < 10; ++n)
        thrd_create(&thr[n], f, NULL);
    for(int n = 0; n < 10; ++n)
        thrd_join(thr[n], NULL);
    printf("The atomic counter is %u\n", acnt);
    printf("The non-atomic counter is %u\n", cnt);
}

সংকলন এবং এর সাথে চালান test_glibc.sh:

#!/usr/bin/env bash
set -eux
gcc \
  -L "${glibc_install}/lib" \
  -I "${glibc_install}/include" \
  -Wl,--rpath="${glibc_install}/lib" \
  -Wl,--dynamic-linker="${glibc_install}/lib/ld-linux-x86-64.so.2" \
  -std=c11 \
  -o test_glibc.out \
  -v \
  test_glibc.c \
  -pthread \
;
ldd ./test_glibc.out
./test_glibc.out

প্রোগ্রামটি প্রত্যাশিত ফলাফলগুলি প্রকাশ করে:

gnu_get_libc_version() = 2.28
The atomic counter is 10000
The non-atomic counter is 8674

Https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_location থেকে কমান্ডটি অভিযোজিত হয়েছে তবে এতে --sysrootএটি ব্যর্থ হয়েছে:

cannot find /home/ciro/glibc/build/install/lib/libc.so.6 inside /home/ciro/glibc/build/install

সুতরাং আমি এটি সরিয়েছি।

lddআউটপুট নিশ্চিত lddকরে যে আমরা যে লাইব্রেরিগুলি তৈরি করেছিলাম তা বাস্তবে প্রত্যাশা অনুযায়ী ব্যবহৃত হচ্ছে:

+ ldd test_glibc.out
        linux-vdso.so.1 (0x00007ffe4bfd3000)
        libpthread.so.0 => /home/ciro/glibc/build/install/lib/libpthread.so.0 (0x00007fc12ed92000)
        libc.so.6 => /home/ciro/glibc/build/install/lib/libc.so.6 (0x00007fc12e9dc000)
        /home/ciro/glibc/build/install/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007fc12f1b3000)

gccসংকলন ডিবাগ আউটপুট শো যে আমার হোস্ট রানটাইম বস্তু ব্যবহার করা হয়, যা খারাপ পূর্বে উল্লিখিত, কিন্তু আমি কিভাবে এটা কাজ করে জানি না হয়, যেমন এটা রয়েছে:

COLLECT_GCC_OPTIONS=/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crt1.o

সেটআপ 1: গ্লিবসি পরিবর্তন করুন

এখন এর সাথে গ্লিবসি পরিবর্তন করুন:

diff --git a/nptl/thrd_create.c b/nptl/thrd_create.c
index 113ba0d93e..b00f088abb 100644
--- a/nptl/thrd_create.c
+++ b/nptl/thrd_create.c
@@ -16,11 +16,14 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */

+#include <stdio.h>
+
 #include "thrd_priv.h"

 int
 thrd_create (thrd_t *thr, thrd_start_t func, void *arg)
 {
+  puts("hacked");
   _Static_assert (sizeof (thr) == sizeof (pthread_t),
                   "sizeof (thr) != sizeof (pthread_t)");

তারপরে পুনরায় সংকলন এবং গ্লোবিক পুনরায় ইনস্টল করুন, এবং আমাদের প্রোগ্রামটি পুনরায় সংকলন এবং পুনরায় চালনা করুন:

cd glibc/build
make -j `nproc`
make -j `nproc` install
./test_glibc.sh

এবং আমরা hackedপ্রত্যাশিত হিসাবে কয়েকবার মুদ্রিত দেখতে পাই ।

এটি আরও নিশ্চিত করে যে আমরা প্রকৃতপক্ষে হোস্টটি নয়, যে সংকলনটি সঙ্কলন করেছি তা ব্যবহার করেছি।

উবুন্টু 18.04 এ পরীক্ষিত।

2 সেটআপ: ক্রসস্টুল-এনজি মূল সেটআপ

এই সেটআপ 1 বিকল্প, এবং এটা সবচেয়ে সঠিক সেটআপ আমি এ পর্যন্ত অর্জন করেছি হল: সবকিছু যতটা সঠিক হিসাবে আমি সি রানটাইম সহ, মান্য করতে পারেন বস্তু যেমন crt1.o, crti.oএবংcrtn.o

এই সেটআপে, আমরা একটি সম্পূর্ণ ডেডিকেটেড জিসিসি টুলচেন সংকলন করব যা আমাদের চাই গ্লিব্যাক ব্যবহার করে।

এই পদ্ধতির একমাত্র ক্ষতিটি হ'ল বিল্ডটি আরও বেশি সময় নেবে। তবে আমি কম কিছু দিয়ে একটি প্রডাকশন সেটআপ ঝুঁকি নেব না।

crosstool-না.গো হ'ল স্ক্রিপ্টগুলির একটি সেট যা জিসিসি, গ্লিবিসি এবং বাইনুটিলস সহ আমাদের জন্য উত্স থেকে সমস্ত কিছু ডাউনলোড এবং সংকলন করে।

হ্যাঁ জিসিসি বিল্ড সিস্টেমটি এতটাই খারাপ যে এর জন্য আমাদের একটি পৃথক প্রকল্পের প্রয়োজন।

এই সেটআপটি কেবল সঠিক নয় কারণ ক্রসস্টুল-এনজি অতিরিক্ত -Wlপতাকা ছাড়াই এক্সিকিউটেবলগুলি তৈরির পক্ষে সমর্থন করে না , যা আমরা নিজেই জিসিসি তৈরি করেছি বলেই অদ্ভুত বোধ করে। তবে সবকিছু কাজ করে বলে মনে হচ্ছে, সুতরাং এটি কেবল কোনও অসুবিধা।

ক্রসস্টুল-এনজি পান, এটি কনফিগার করুন এবং এটি তৈরি করুন:

git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
git checkout a6580b8e8b55345a5a342b5bd96e42c83e640ac5
export CT_PREFIX="$(pwd)/.build/install"
export PATH="/usr/lib/ccache:${PATH}"
./bootstrap
./configure --enable-local
make -j `nproc`
./ct-ng x86_64-unknown-linux-gnu
./ct-ng menuconfig
env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`

বিল্ডটি প্রায় ত্রিশ মিনিট থেকে দুই ঘন্টা সময় নেয়।

একমাত্র বাধ্যতামূলক কনফিগারেশন বিকল্পটি আমি দেখতে পাচ্ছি, এটি সঠিক হোস্টেল কার্নেল শিরোনামগুলি ব্যবহার করতে আপনার হোস্ট কার্নেল সংস্করণের সাথে মেলে। এর সাথে আপনার হোস্ট কার্নেলের সংস্করণটি সন্ধান করুন:

uname -a

যা আমাকে দেখায়:

4.15.0-34-generic

তাই menuconfigআমি কি:

  • Operating System
    • Version of linux

সুতরাং আমি নির্বাচন করুন:

4.14.71

এটি প্রথম সমান বা পুরানো সংস্করণ। কার্নেলটি পিছনের দিকে সামঞ্জস্যপূর্ণ হওয়ার কারণে এটি আরও পুরানো হতে হবে।

সেটআপ 2: .চ্ছিক কনফিগারেশন

.configআমরা উত্পন্ন যে ./ct-ng x86_64-unknown-linux-gnuআছে:

CT_GLIBC_V_2_27=y

এটি পরিবর্তন করতে, menuconfigকরণীয়:

  • C-library
  • Version of glibc

সংরক্ষণ করুন .configএবং বিল্ডটি দিয়ে চালিয়ে যান।

অথবা, আপনি যদি নিজের নিজস্ব গ্লিবসি উত্স ব্যবহার করতে চান, যেমন সর্বশেষতম গিট থেকে গ্লিবসি ব্যবহার করতে, এই জাতীয়ভাবে এগিয়ে যান :

  • Paths and misc options
    • Try features marked as EXPERIMENTAL: সত্য হিসাবে সেট করা
  • C-library
    • Source of glibc
      • Custom location: হ্যাঁ বলুন
      • Custom location
        • Custom source location: আপনার glibc উত্সযুক্ত ডিরেক্টরিতে নির্দেশ করুন

যেখানে glibc হিসাবে ক্লোন করা হয়েছিল:

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout glibc-2.28

সেটআপ 2: এটি পরীক্ষা করে দেখুন

একবার আপনি যে সরঞ্জামটি চান সেটি বানিয়ে ফেললে এটি পরীক্ষা করে দেখুন:

#!/usr/bin/env bash
set -eux
install_dir="${CT_PREFIX}/x86_64-unknown-linux-gnu"
PATH="${PATH}:${install_dir}/bin" \
  x86_64-unknown-linux-gnu-gcc \
  -Wl,--dynamic-linker="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib/ld-linux-x86-64.so.2" \
  -Wl,--rpath="${install_dir}/x86_64-unknown-linux-gnu/sysroot/lib" \
  -v \
  -o test_glibc.out \
  test_glibc.c \
  -pthread \
;
ldd test_glibc.out
./test_glibc.out

সবকিছুই সেটআপ 1-তে কাজ করছে বলে মনে হয়, এখন বাদে সঠিক রানটাইম অবজেক্টগুলি ব্যবহৃত হয়েছিল:

COLLECT_GCC_OPTIONS=/home/ciro/crosstool-ng/.build/install/x86_64-unknown-linux-gnu/bin/../x86_64-unknown-linux-gnu/sysroot/usr/lib/../lib64/crt1.o

সেটআপ 2: দক্ষ গ্লিবসি পুনঃসংশোধনের প্রচেষ্টা ব্যর্থ হয়েছে

এটি নীচে বর্ণিত হিসাবে ক্রসস্টুল-এনজি দিয়ে সম্ভব বলে মনে হচ্ছে না।

আপনি যদি কেবল পুনর্নির্মাণ করেন;

env -u LD_LIBRARY_PATH time ./ct-ng build CT_JOBS=`nproc`

তারপরে কাস্টম গ্লিবিসি উত্সের অবস্থানের আপনার পরিবর্তনগুলি বিবেচনায় নেওয়া হয় তবে এটি স্ক্র্যাচ থেকে সবকিছু তৈরি করে, এটি পুনরুক্তি বিকাশের জন্য অকেজো করে তোলে।

আমরা যদি:

./ct-ng list-steps

এটি বিল্ড স্টেপগুলির একটি সুন্দর ওভারভিউ দেয়:

Available build steps, in order:
  - companion_tools_for_build
  - companion_libs_for_build
  - binutils_for_build
  - companion_tools_for_host
  - companion_libs_for_host
  - binutils_for_host
  - cc_core_pass_1
  - kernel_headers
  - libc_start_files
  - cc_core_pass_2
  - libc
  - cc_for_build
  - cc_for_host
  - libc_post_cc
  - companion_libs_for_target
  - binutils_for_target
  - debug
  - test_suite
  - finish
Use "<step>" as action to execute only that step.
Use "+<step>" as action to execute up to that step.
Use "<step>+" as action to execute from that step onward.

অতএব, আমরা দেখতে পাই যে বেশ কয়েকটি জিসিসি পদক্ষেপের সাথে জড়িত গ্লিবসি পদক্ষেপ রয়েছে, বিশেষত উল্লেখযোগ্যভাবে libc_start_filesআগে চলে আসে cc_core_pass_2, এটি সম্ভবত সবচেয়ে ব্যয়বহুল পদক্ষেপ এক সাথে হয়cc_core_pass_1

মাত্র এক ধাপ তৈরি করতে, আপনাকে প্রথমে অন্তর্বর্তী .configবিল্ডের বিকল্পটিতে "মধ্যবর্তী পদক্ষেপগুলি সংরক্ষণ করুন" সেট করতে হবে :

  • Paths and misc options
    • Debug crosstool-NG
      • Save intermediate steps

এবং তারপরে আপনি চেষ্টা করতে পারেন:

env -u LD_LIBRARY_PATH time ./ct-ng libc+ -j`nproc`

কিন্তু দুর্ভাগ্যক্রমে, এখানে +উল্লিখিত হিসাবে প্রয়োজনীয়: https://github.com/crosstool-ng/crosstool-ng/issues/1033#issuecomment-424877536

তবে নোট করুন যে একটি মধ্যবর্তী পদক্ষেপে পুনরায় আরম্ভ করার পরে ইনস্টলেশন ডিরেক্টরিটি সেই পদক্ষেপের সময় থাকা অবস্থায় পুনরায় সেট করে। অর্থাৎ, আপনার একটি পুনর্নির্মাণ libc থাকবে - তবে এই libc দিয়ে কোনও চূড়ান্ত সংকলক নির্মিত হয়নি (এবং অতএব, libstdc ++ এর মতো কোনও সংকলক লাইব্রেরি নেই)।

এবং মূলত এখনও পুনর্নির্মাণটি বিকাশের পক্ষে কার্যকর হতে ধীর করে তোলে এবং ক্রসস্টুল-এনজি প্যাচ না করে কীভাবে এটি পরাভূত হবে তা আমি দেখতে পাই না।

তদ্ব্যতীত, libcপদক্ষেপটি থেকে শুরু করে উত্স থেকে আর অনুলিপি করা হয়নি বলে মনে হয় Custom source location, এই পদ্ধতিটি অকেজো করে তোলে।

বোনাস: stdlibc ++

আপনি যদি সি ++ স্ট্যান্ডার্ড লাইব্রেরিতে আগ্রহী হন তবে একটি বোনাস: কীভাবে সম্পাদনা করবেন এবং জিসিসি libstdc ++ সি ++ স্ট্যান্ডার্ড লাইব্রেরি উত্সটি পুনর্নির্মাণ করবেন?


6

আপনি কী নিক্স ব্যবহার করতে পারেন http://nixos.org/nix/ ?

নিক্স বহু-ব্যবহারকারী প্যাকেজ পরিচালনার সহায়তা করে: একাধিক ব্যবহারকারী নিরাপদে একটি সাধারণ নিক্স স্টোর ভাগ করতে পারেন, সফ্টওয়্যার ইনস্টল করার জন্য রুট সুবিধার দরকার নেই এবং প্যাকেজের বিভিন্ন সংস্করণ ইনস্টল ও ব্যবহার করতে পারেন।


4

@ এমএসবি একটি নিরাপদ সমাধান দেয়।

যখন আমি আমি এই সমস্যা পূরণ import tensorflow as tfconda পরিবেশে মধ্যে CentOS 6.5যা হয়েছে শুধুমাত্র glibc-2.12

ImportError: /lib64/libc.so.6: version `GLIBC_2.16' not found (required by /home/

আমি কিছু বিশদ সরবরাহ করতে চাই:

প্রথমে glibcআপনার হোম ডিরেক্টরিতে ইনস্টল করুন :

mkdir ~/glibc-install; cd ~/glibc-install
wget http://ftp.gnu.org/gnu/glibc/glibc-2.17.tar.gz
tar -zxvf glibc-2.17.tar.gz
cd glibc-2.17
mkdir build
cd build
../configure --prefix=/home/myself/opt/glibc-2.17  # <-- where you install new glibc
make -j<number of CPU Cores>  # You can find your <number of CPU Cores> by using **nproc** command
make install

দ্বিতীয়ত, প্যাচেলফ ইনস্টল করতে একই পদ্ধতি অনুসরণ করুন ;

তৃতীয়ত, আপনার পাইথনটি প্যাচ করুন:

[myself@nfkd ~]$ patchelf --set-interpreter /home/myself/opt/glibc-2.17/lib/ld-linux-x86-64.so.2 --set-rpath /home/myself/opt/glibc-2.17/lib/ /home/myself/miniconda3/envs/tensorflow/bin/python

@ এমএসবি দ্বারা উল্লিখিত

এখন আমি ব্যবহার করতে পারেন tensorflow-2.0 alphaমধ্যে CentOS 6.5

রেফ: https://serverkurma.com/linux/how-to-update-glibc-newer-version-on-centos-6-x/


2

আমি নিশ্চিত নই যে প্রশ্নটি এখনও প্রাসঙ্গিক, তবে সমস্যা সমাধানের আরও একটি উপায় রয়েছে: ডকার। কেউ সোর্স ডিস্ট্রিবিউশনের প্রায় শূন্য পাত্রে ইনস্টল করতে পারেন (বিকাশের জন্য ব্যবহৃত বিতরণ) এবং ফাইলগুলি কন্টেইনারে অনুলিপি করতে পারেন। এইভাবে ক্রুটের জন্য আপনার প্রয়োজনীয় ফাইল সিস্টেম তৈরি করার দরকার নেই।


1

আপনি যদি দ্বিতীয় আউটপুটটি ঘনিষ্ঠভাবে দেখে থাকেন তবে দেখতে পাবেন লাইব্রেরির জন্য নতুন অবস্থান ব্যবহৃত হয়েছে। সম্ভবত এখনও রয়েছে এমন গ্রন্থাগারগুলি যা গ্লিবসিটির অংশ।

আমি আরও মনে করি যে আপনার প্রোগ্রাম দ্বারা ব্যবহৃত সমস্ত গ্রন্থাগারগুলি glibc c সংস্করণের বিরুদ্ধে সংকলিত করা উচিত। আপনার যদি প্রোগ্রামটির উত্স কোডটিতে অ্যাক্সেস থাকে তবে একটি নতুন সংকলনটি সেরা সমাধান হিসাবে উপস্থিত হয়।


1

"নিযুক্ত রাশিয়ান" সেরা উত্তরগুলির মধ্যে একটি, এবং আমি মনে করি যে অন্যান্য প্রস্তাবিত উত্তরগুলি কাজ না করে। কারণটি হ'ল কারণ যখন কোনও অ্যাপ্লিকেশন প্রথম তৈরি করা হয় তখন এর প্রয়োজনীয় সমস্ত এপিআই সংকলন সময়ে সমাধান করা হয়। "এলডিডি" ব্যবহার করে আপনি সমস্ত স্ট্যাটিকালি লিঙ্কযুক্ত নির্ভরতা দেখতে পাবেন:

ldd /usr/lib/firefox/firefox
    linux-vdso.so.1 =>  (0x00007ffd5c5f0000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f727e708000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f727e500000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f727e1f8000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f727def0000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f727db28000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f727eb78000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f727d910000)

তবে রানটাইম চলাকালীন ফায়ারফক্স আরও অনেক গতিশীল লাইব্রেরি লোড করবে, যেমন (ফায়ারফক্সের জন্য) অনেকগুলি "গ্লিব" লেবেলযুক্ত লাইব্রেরি লোড হয়েছে (যদিও স্ট্যাটিকালি লিঙ্কযুক্ত কোনও নেই):

 /usr/lib/x86_64-linux-gnu/libdbus-glib-1.so.2.2.2
 /lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0
 /usr/lib/x86_64-linux-gnu/libavahi-glib.so.1.0.2

অনেক সময়, আপনি দেখতে পাচ্ছেন যে একটি সংস্করণের নামগুলি অন্য সংস্করণে নরম সংযুক্ত রয়েছে। উদাহরণ:

lrwxrwxrwx 1 root root     23 Dec 21  2014 libdbus-glib-1.so.2 -> libdbus-glib-1.so.2.2.2
-rw-r--r-- 1 root root 160832 Mar  1  2013 libdbus-glib-1.so.2.2.2

এর অর্থ এটি একটি সিস্টেমে "লাইব্রেরি" এর বিভিন্ন সংস্করণ বিদ্যমান - এটি একই ফাইল হওয়ায় সমস্যা নয় এবং অ্যাপ্লিকেশনগুলির একাধিক সংস্করণ নির্ভরতা থাকলে এটি সামঞ্জস্যতা সরবরাহ করবে।

অতএব, সিস্টেম স্তরে, সমস্ত গ্রন্থাগার একে অপরের উপর নির্ভরশীল এবং কেবলমাত্র LD_PRELOAD বা LD_LIBRARY_PATH কে চালানোর মাধ্যমে লাইব্রেরিগুলি লোডিং অগ্রাধিকার পরিবর্তন করতে সহায়তা করবে না - এমনকি এটি লোড করতে পারে, রানটাইম এখনও ক্রাশ হতে পারে।

http://lightofdawn.org/wiki/wiki.cgi/-wiki/NewAppsOnOldGlibc

সেরা বিকল্পটি ক্রুট (সংক্ষেপে ER দ্বারা উল্লিখিত): তবে এর জন্য আপনাকে পুরো পরিবেশটি পুনরায় তৈরি করতে হবে যেখানে মূল বাইনারি কার্যকর হয় - সাধারণত / lib, / usr / lib /, / usr / lib / x86 ইত্যাদি থেকে শুরু করে etc. আপনি হয় "বিল্ড্রুট" বা ইয়োকোপ্রজেক্ট ব্যবহার করতে পারেন, বা বিদ্যমান ডিস্ট্রো পরিবেশ থেকে কেবল ট্যার ব্যবহার করতে পারেন। (যেমন ফেডোরা / সুস ইত্যাদি)।


0

আমি যখন উবুন্টু যথাযথভাবে (glibc-2.15) একটি ক্রোমিয়াম-ব্রাউজার চালাতে চেয়েছি তখন আমি (সাধারণ) বার্তাটি পেয়েছি "... libc.so.6: সংস্করণ` GLIBC_2.19 'পাওয়া যায়নি ... "। আমি এই বিষয়টি বিবেচনা করে দেখলাম যে ফাইলগুলি পারমাটিকভাবে প্রয়োজন হয় না, তবে কেবল শুরু করার জন্য। সুতরাং আমি ব্রাউজারের জন্য প্রয়োজনীয় ফাইলগুলি সংগ্রহ করেছি এবং সুডো তৈরি করেছি এবং একটি মিনি-গ্লিবসি -২.১৯-পরিবেশ তৈরি করেছি, ব্রাউজারটি শুরু করেছি এবং তারপরে আবার মূল ফাইলগুলি অনুলিপি করেছি। প্রয়োজনীয় ফাইলগুলি র‍্যামে রয়েছে এবং মূল গ্লিবসি একই is

as root
the files (*-2.15.so) already exist 

mkdir -p /glibc-2.19/i386-linux-gnu

/glibc-2.19/ld-linux.so.2 -> /glibc-2.19/i386-linux-gnu/ld-2.19.so
/glibc-2.19/i386-linux-gnu/libc.so.6 -> libc-2.19.so
/glibc-2.19/i386-linux-gnu/libdl.so.2 -> libdl-2.19.so
/glibc-2.19/i386-linux-gnu/libpthread.so.0 -> libpthread-2.19.so

mkdir -p /glibc-2.15/i386-linux-gnu

/glibc-2.15/ld-linux.so.2 -> (/glibc-2.15/i386-linux-gnu/ld-2.15.so)
/glibc-2.15/i386-linux-gnu/libc.so.6 -> (libc-2.15.so)
/glibc-2.15/i386-linux-gnu/libdl.so.2 -> (libdl-2.15.so)
/glibc-2.15/i386-linux-gnu/libpthread.so.0 -> (libpthread-2.15.so)

ব্রাউজারটি চালানোর জন্য স্ক্রিপ্ট:

#!/bin/sh
sudo cp -r /glibc-2.19/* /lib
/path/to/the/browser &
sleep 1
sudo cp -r /glibc-2.15/* /lib
sudo rm -r /lib/i386-linux-gnu/*-2.19.so
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.