GLIBC_2.29 kann für avrdude auch nach dem Herunterladen nicht gefunden werden

GLIBC_2.29 kann für avrdude auch nach dem Herunterladen nicht gefunden werden

Ich habe ein bisschen Probleme mit der Verwendung avrdudevonBlitzmein Mikrocontroller.

Es hängt davon ablibm.so.6 GLIBC_2.29die es nicht finden kann. Es sucht dort, /usr/lib/libm.so.6wo sich diese Datei tatsächlich befindet, ABER sie befindet sich auch in /lib/lib.so.6.

Als ich also rannte

sudo pacman -S glibc 

um die Bibliothek zu installieren/aktualisierenhttps://www.archlinux.org/packages/core/x86_64/glibc/

Ich bin sehr sicher, dass ich es nur installiert habe, um /lib/

Aber avrdudeich suche weiter und /usr/libfinde es immer noch nicht. Ich habe Schwierigkeiten, den Sinn dieser beiden Verzeichnisse zu verstehen, da sie die Dinge eher durcheinanderbringen als mir in meinem Fall helfen.

Wie mache ich es richtig?

BEARBEITEN

Ich wollte etwas Dummes tun, also habe ich es getan cp /lib/libm.so.6 /usr/lib/libm.o.6, aber der cpBefehl sagt mir, dass die Dateien gleich sind.

Jetzt verstehe ich nicht, warum ich avrdudedie richtige Version von GLIBC nicht finden kann, da diese (soweit ich das erkennen kann) ordnungsgemäß aktualisiert wird.

Antwort1

Bitte beachten Sie, dass die Installation glibcunvollständig ist. C runtime. Zur Vervollständigung C runtimemüssen Sie möglicherweise zusätzliche Header kopieren, die zum verwendeten Compiler passen, da die Verwendung von --sysrootderen Suche auf beschränkt sysroot.

Es ist durchaus möglich, mehrere Versionen von glibc auf demselben System zu haben (das passiert uns jeden Tag).

Sie müssen jedoch wissen, dass glibc aus vielen Teilen besteht (mehr als 200 gemeinsam genutzte Bibliotheken), die alle übereinstimmen müssen. Einer dieser Teile ist ld-linux.so.2 und muss mit libc.so.6 übereinstimmen, sonst treten die angezeigten Fehler auf.

Der absolute Pfad zu ld-linux.so.2 wird beim Verknüpfen fest in die ausführbare Datei codiert und kann nach Abschluss des Verknüpfens nicht mehr einfach geändert werden.

Um eine ausführbare Datei zu erstellen, die mit der neuen glibc funktioniert, gehen Sie wie folgt vor:

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

Die -rpathLinker-Option veranlasst den Runtime Loader, nach Bibliotheken zu suchen /path/to/newglibc(so dass Sie sie vor dem Ausführen nicht festlegen müssen LD_LIBRARY_PATH) und die -dynamic-linkerOption „backt“ den Pfad zur Korrektur ld-linux.so.2in die Anwendung ein.

Wenn Sie die Anwendung nicht erneut verknüpfen können myapp(z. B. weil es sich um eine Binärdatei eines Drittanbieters handelt), ist nicht alles verloren, aber es wird schwieriger. Eine Lösung besteht darin, eine geeignete chrootUmgebung dafür einzurichten. Eine andere Möglichkeit ist die Verwendung vonAbonnierenund einBinäreditor.

LÖSUNG #1

LD_PRELOAD='mylibc.so anotherlib.so' program

Lösung Nr. 2

Kompilieren Sie Ihre eigene glibc ohne dedizierten GCC und verwenden Sie sie

Dieses Setup funktioniert möglicherweise und ist schnell, da es nicht die gesamte GCC-Toolchain neu kompiliert, sondern nur glibc.

Es ist jedoch nicht zuverlässig, da es Host-C-Laufzeitobjekte wie verwendet crt1.o, crti.ound crtn.ovon glibc bereitgestellt wird. Dies wird erwähnt unter:https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_locationDiese Objekte führen die frühe Einrichtung durch, auf die glibc angewiesen ist, daher würde es mich nicht überraschen, wenn Dinge auf wundervolle und unglaublich subtile Weise abstürzen würden.

Eine zuverlässigere Einrichtung finden Sie weiter unten unter Einrichtung 2.

Lokal erstellen glibcund installieren:

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`

Setup 1: Überprüfen des Builds

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.
     * https://stackoverflow.com/questions/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);
}

Kompilieren und ausführen mit 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

Das Programm gibt die erwartete Ausgabe aus:

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

Befehl adaptiert vonhttps://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_locationaber --sysroot ließ es mit folgendem fehlschlagen:

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

also habe ich es entfernt.

Die ldd-Ausgabe bestätigt, dass das gerade erstellte ldd und die Bibliotheken tatsächlich wie erwartet verwendet werden:

+ 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)

Die Debug-Ausgabe der GCC-Kompilierung zeigt, dass meine Host-Laufzeitobjekte verwendet wurden, was, wie bereits erwähnt, schlecht ist, aber ich weiß nicht, wie ich das umgehen kann. Sie enthält beispielsweise:

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

Setup 1: glibc ändern

Lassen Sie uns nun glibc wie folgt ändern:

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)");

Dann kompilieren und installieren Sie glibc neu und kompilieren und führen Sie unser Programm erneut aus:

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

und wir sehen, dass „gehackt“ wie erwartet ein paar Mal gedruckt wird.

Dies bestätigt weiter, dass wir tatsächlich die von uns kompilierte glibc verwendet haben und nicht die des Hosts.

Getestet auf Ubuntu 18.04.

Quellen:

https://stackoverflow.com/questions/847179/multiple-glibc-libraries-on-a-single-host/851229#851229

https://sourceware.org/glibc/wiki/Testing/Builds?action=recallrev=21#Compile_against_glibc_in_an_installed_location

verwandte Informationen