Rivedendo il backtrace del server X, il programma
/usr/lib/xorg/Xorg (il server X) genera una segnale di SIGABRT (signal=6) che consegue alla generazione di un segnale di
SIGSEGV (signal=11) ovvero un segnale di "Invalid memory reference" evocato all'interno della funzione __strcmp_ssse3. Quindi, ipotizzando che la funzione __strcmp_ssse3() non sia affetta da bug, il SIGSEGV è causato da uno degli argomenti passati alla funzione
strcmp():
- Codice: Seleziona tutto
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
[..]
#5 0x000055e8f9a80201 in OsSigHandler (unused=<optimized out>, sip=<optimized out>, signo=11)
at ../../../../os/osinit.c:156
#6 OsSigHandler (signo=11, sip=<optimized out>, unused=<optimized out>) at ../../../../os/osinit.c:110
#7 <signal handler called>
#8 __strcmp_ssse3 () at ../sysdeps/x86_64/multiarch/../strcmp.S:174
La funzione
__strcmp_ssse3() è invocata come sostituto ottimizzato della funzione strcmp() nella libreria libc6 (è una funzione di libreria standard del linguaggio C che si occupa semplicemente di confrontare due stringhe per verificare se sono uguali oppure no).
L'errore di SIGSEGV, molto probabilmente, si genera perché uno dei due argomenti passati alla funzione strcmp() punta ad un'area di memoria a cui non può avere accesso (probabilmente, è usato un indirizzo errato).
Di seguito, riporto il codice in linguaggio C della funzione
epoxy_internal_has_gl_extension() della libreria libepoxy [0], all'interno della quale è invocata la funzione strcmp() che ho evidenziato con un "-->":
- Codice: Seleziona tutto
static bool
epoxy_internal_has_gl_extension(const char *ext, bool invalid_op_mode)
{
if (epoxy_gl_version() < 30) {
const char *exts = (const char *)glGetString(GL_EXTENSIONS);
if (!exts)
return invalid_op_mode;
return epoxy_extension_in_string(exts, ext);
} else {
int num_extensions;
int i;
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
if (num_extensions == 0)
return invalid_op_mode;
for (i = 0; i < num_extensions; i++) {
const char *gl_ext = (const char *)glGetStringi(GL_EXTENSIONS, i);
if (!gl_ext)
return false;
--> if (strcmp(ext, gl_ext) == 0)
return true;
}
return false;
}
}
Analizzando il coredump del server X con il debugger, la chiamata della funzione strcmp(), la variabile
const char *ext risulta essere correttamente valorizzata e punta ad una stringa (array di caratteri "null terminated"):
- Codice: Seleziona tutto
Name : ext
Details:0x7f2f9dc31393 "GL_OES_EGL_image"
Invece, per quanto riguarda la variabile
const char *gl_ext, il debugger non riesce ad esplorarla (perché in fase di compilazione del server X essa è stata ottimizzata e, quindi, è gestita a livello di codice binario direttamente tramite registri della CPU e non tramite locazioni di memoria).
Ciò non di meno, necessariamente deve essere questa la variabile che punta ad un'area di memoria a cui non è consentito l'accesso e che genera l'errore, poiché è l'unica altra variabile che è passata alla funzione strcmp.
Con il debugger, è possibile analizzare il codice macchina della chiamata della funzione strcmp e risulta il seguente codice:
- Codice: Seleziona tutto
543 if (strcmp(ext, gl_ext) == 0)
00007f2f9db5d0c0: mov %rax,%rsi
00007f2f9db5d0c3: mov %rbp,%rdi
00007f2f9db5d0c6: callq 0x7f2f9dafa070 <strcmp@plt>
00007f2f9db5d0cb: test %eax,%eax
00007f2f9db5d0cd: je 0x7f2f9db5d0f0 <epoxy_internal_has_gl_extension+192>
Analizzando con il debugger i registri della CPU %rsi e %rdi, risulta che (in notazione esadecimale):
- Codice: Seleziona tutto
rsi = 0xfffffffffffffc18
rdi = 0x7f2f9dc31393
Come puoi vedere il registro
rdi contiene l'indirizzo di memoria della variabile
const char *gl_ext, mentre il registro
rsi contiene un indirizzo l'indirizzo di memoria 0xfffffffffffffc18 e quest'ultimo è un indirizzo di memoria generalmente riservato al kernel, quindi da non passare ad una funzione che opera in spazio utente.
La variabile
const char *gl_ext nel codice sorgente è valorizzata in un unico punto della funzione [0]:
- Codice: Seleziona tutto
const char *gl_ext = (const char *)glGetStringi(GL_EXTENSIONS, i);
---
[0]
https://sources.debian.org/src/libepoxy/1.5.3-0.1/src/dispatch_common.c/?hl=96#L543