Tengo este fragmento de código que falla cuando se ejecuta en Ubuntu 14.04 en una CPU compatible con AMD64:
#include <inttypes.h>
#include <stdlib.h>
#include <sys/mman.h>
int main()
{
uint32_t sum = 0;
uint8_t *buffer = mmap(NULL, 1<<18, PROT_READ,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
uint16_t *p = (buffer + 1);
int i;
for (i=0;i<14;++i) {
//printf("%d\n", i);
sum += p[i];
}
return sum;
}
Esto solo falla si la memoria se asigna usando mmap
. si uso malloc
un búfer en la pila o una variable global que no falla.
Si reduzco el número de iteraciones del ciclo a menos de 14, ya no fallará. Y si imprimo el índice de la matriz desde dentro del ciclo, ya no fallará.
¿Por qué el acceso a la memoria no alineada falla de segmento en una CPU que puede acceder a direcciones no alineadas, y por qué solo en circunstancias tan específicas?
No se puede reproducir esto en Debian. ¿Puedes publicar el código ensamblador generado? (Si está utilizando
gcc
puede obtener la salida del ensamblador con el-S
opción, la salida del ensamblador se escribirá en un.s
expediente.)– cmaster – reincorporar a monica
27 de noviembre de 2017 a las 12:22
¿Estás seguro de que tu
mmap()
tiene éxito? Tal vez devuelve un error…– CTX
27 de noviembre de 2017 a las 12:25
¿Qué sucede si llamas a malloc y luego agregas la línea?
volatile uint8_t dummy = buffer[0];
justo después de la llamada malloc? Mismo error? Lo que busco es que la asignación real del montón se retrase hasta que los datos se utilicen realmente. Dado que se garantiza que el contenido del búfer devuelto por malloc contiene valores no especificados, el compilador de C podría pensar que en realidad no tiene que asignar nada.– Lundin
27 de noviembre de 2017 a las 12:25
@Lundin: estás suponiendo que el
malloc
intrínseco puede omitirse por completo?–Oliver Charlesworth
27 de noviembre de 2017 a las 12:27
@Lundin pero el OP afirma que obras con
malloc()
y no conmmap()
– CTX
27 de noviembre de 2017 a las 12:29