GLIBC_2.29 no se puede encontrar para avrdude incluso después de descargarlo

GLIBC_2.29 no se puede encontrar para avrdude incluso después de descargarlo

Me cuesta un poco avrdudeusardestellomi microcontrolador.

Depende delibm.so.6 GLIBC_2.29que no puede encontrar. Busca debajo /usr/lib/libm.so.6dónde reside realmente este archivo, PERO también reside en /lib/lib.so.6.

Así que mientras corría

sudo pacman -S glibc 

para instalar/actualizar la bibliotecahttps://www.archlinux.org/packages/core/x86_64/glibc/

Estoy muy seguro de que lo instalé solo en /lib/.

Pero como avrdudelo estoy investigando, /usr/libtodavía no lo encuentro. Me cuesta entender el sentido de estos dos directorios, ya que arruinan un poco las cosas y no ayudan en mi caso.

¿Cómo puedo hacerlo correctamente?

EDITAR

Quería hacer algo estúpido y lo hice, cp /lib/libm.so.6 /usr/lib/libm.o.6pero el cpcomando me dice que los archivos son iguales.

Ahora no entiendo por qué avrdudeno puedo encontrar la versión correcta de GLIBC ya que está actualizada correctamente (hasta donde puedo ver).

Respuesta1

Tenga en cuenta que el archivo instalado glibcestá incompleto. C runtime. Para completarlo, C runtimees posible que deba copiar encabezados adicionales que coincidan con el compilador que está utilizando, ya que el uso de --sysrootrestringirá su búsqueda al archivo sysroot.

Es muy posible tener varias versiones de glibc en el mismo sistema (lo hacemos todos los días).

Sin embargo, debe saber que glibc consta de muchas piezas (más de 200 bibliotecas compartidas) que deben coincidir. Una de las piezas es ld-linux.so.2 y debe coincidir con libc.so.6, o verá los errores que está viendo.

La ruta absoluta a ld-linux.so.2 está codificada en el ejecutable en el momento del enlace y no se puede cambiar fácilmente una vez finalizado el enlace.

Para crear un ejecutable que funcione con el nuevo glibc, haga esto:

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

La -rpathopción del vinculador hará que el cargador en tiempo de ejecución busque bibliotecas /path/to/newglibc(para que no tenga que configurarlas LD_LIBRARY_PATHantes de ejecutarlo), y la -dynamic-linkeropción "preparará" la ruta para corregirla ld-linux.so.2en la aplicación.

Si no puedes volver a vincular la myappaplicación (por ejemplo, porque es un binario de terceros), no todo está perdido, pero se vuelve más complicado. Una solución es crear un chrootentorno adecuado para ello. Otra posibilidad es utilizarrtldiy uneditor binario.

SOLUCIÓN #1

LD_PRELOAD='mylibc.so anotherlib.so' program

Solución #2

compila tu propio glibc sin GCC dedicado y úsalo

Esta configuración podría funcionar y es rápida ya que no recompila toda la cadena de herramientas de GCC, solo glibc.

Pero no es confiable ya que utiliza objetos de tiempo de ejecución del host C como crt1.o, crti.oy crtn.oproporcionados por glibc. Esto se menciona en:https://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_locationEsos objetos realizan una configuración temprana en la que se basa glibc, por lo que no me sorprendería que las cosas fallaran de maneras maravillosas e increíblemente sutiles.

Para una configuración más confiable, consulte Configuración 2 a continuación.

Construya glibce instale localmente:

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`

Configuración 1: verificar la compilación

prueba_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);
}

Compile y ejecute con 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

El programa genera lo esperado:

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

Comando adaptado dehttps://sourceware.org/glibc/wiki/Testing/Builds?action=recall&rev=21#Compile_against_glibc_in_an_installed_locationpero --sysroot hizo que fallara con:

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

así que lo eliminé.

La salida de ldd confirma que el ldd y las bibliotecas que acabamos de crear se están utilizando como se esperaba:

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

El resultado de depuración de la compilación de gcc muestra que se utilizaron los objetos de tiempo de ejecución de mi host, lo cual es malo como se mencionó anteriormente, pero no sé cómo solucionarlo, por ejemplo, contiene:

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

Configuración 1: modificar glibc

Ahora modifiquemos glibc con:

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

Luego vuelva a compilar y reinstalar glibc, y vuelva a compilar y ejecutar nuestro programa:

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

y vemos impresos pirateados varias veces como se esperaba.

Esto confirma aún más que en realidad utilizamos el glibc que compilamos y no el host.

Probado en Ubuntu 18.04.

Fuentes:

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

información relacionada