Ver la versión completa : Dirección de memoria problemática
Puck2099
21/03/2006, 07:02
Hola,
Tengo un problema con una cosilla que estoy portando, a ver si me podéis echar una mano :)
El caso es que tenemos el siguiente código:
new = (memblock_t *) ((byte *)base + size );
new->size = extra;
new->user = NULL; // free block
new->tag = 0;
new->prev = base;
new->next = base->next;
new->next->prev = new;
base->next = new;
base->size = size;
Pues bien, al hacer "new->next->prev = new;" el programa peta con un Segmentation Fault.
Justo antes de hacer esa asignación, usando el gdb tenemos lo siguiente:
(gdb) p new
$15 = (memblock_t *) 0x4000103d
(gdb) p new->next
$16 = (struct memblock_s *) 0x24400010
(gdb) p new->next->prev
Cannot access memory at address 0x24400020
¿A qué se podría deber que no pudiera acceder a esa dirección de memoria?, ¿podría ser una parte de memoria reservada?
Muchas gracias por la ayuda :brindis:
LukStarkiller
21/03/2006, 07:33
No sera un cacho a evitar, me recuerda a esa opcion de muchas placas base (memory hole on ...)
Puck, ¿no te parece una dirección de memoria demasiado "elevada"? Vamos, que de esto yo casi ni pajolera idea sin documentación "oficial" de la GP2X en mano, sobre todo en lo que se refiere al mapa de memoria, pero si la GP2X tiene aprox. 64 MB de RAM, lo pasamos a bytes, el número decimal resultante a hexa debe salir igual o menos de 0x04000000 como máximo de direcciones físicas (y el kernel Linux está accediendo hasta los primeros 32 MB), que es bastante inferior a 0x24400020, vamos, que puedo estar equivocado pues lo digo con más dudas que otra cosa o que 0x24400020 sea una dirección virtual (despues de todo el arm920t tiene MMU por lo que el kernel Linux podría hacer uso de ella) o algo que no he tenido en cuenta por desconocimiento :confused:
Puck2099
21/03/2006, 16:30
Puck, ¿no te parece una dirección de memoria demasiado "elevada"? Vamos, que de esto yo casi ni pajolera idea sin documentación "oficial" de la GP2X en mano, sobre todo en lo que se refiere al mapa de memoria, pero si la GP2X tiene aprox. 64 MB de RAM, lo pasamos a bytes, el número decimal resultante a hexa debe salir igual o menos de 0x04000000 como máximo de direcciones físicas (y el kernel Linux está accediendo hasta los primeros 32 MB), que es bastante inferior a 0x24400020, vamos, que puedo estar equivocado pues lo digo con más dudas que otra cosa o que 0x24400020 sea una dirección virtual (despues de todo el arm920t tiene MMU por lo que el kernel Linux podría hacer uso de ella) o algo que no he tenido en cuenta por desconocimiento :confused:
Pues la verdad es que no tengo ni idea tío, pero mirando la siguiente imagen que posteó alguien en el foro, parece que está esa dirección dentro del rango de la SDRAM, ¿no?
http://www.gp32spain.com/foros/attachment.php?attachmentid=8945&stc=1&d=1137270960
Por otro lado, el compilador y/o SO debería asignarle una dirección de memoria válida, ¿no?
Saludos
< - >
pero si la GP2X tiene aprox. 64 MB de RAM, lo pasamos a bytes, el número decimal resultante a hexa debe salir igual o menos de 0x04000000 como máximo de direcciones físicas
Por cierto, estoy echando cuentas y me salen muchas menos direcciones de memoria.
Cada dirección de memoria constará de 4 bytes, ¿no? Entonces, tendríamos 0x4000 direcciones, ¿o estoy yo equivocado?
Y no será que lo que intentas que apunte a new no existe? Es decir, que tan sólo haya un "objeto", que base->next sea un NULL y por tanto tb lo sea new->next, i al jugar con el siguiente puntero next->prev, se joda?
anibarro
21/03/2006, 18:03
Puck sin ver el resto del programa es dificil decir algo, pero el asignar direcciones de memoria sumando valores a direcciones previas, es arriesgado porque no sabes si estara libre o no o si existira...eso es lo que parece que puede hacer ese codigo, pero no estoy seguro :s
Si oankali lo leyese te lo diria en un momento, que controla un huevo de eso
Y digo yo (a riesgo de parecer estúpido)... ¿no podría ocurrir que base->next (y por tanto new->next) estuviese sin inicializar y contenga basura? Eso explicaría que se apunte a una zona "indefinida", digamos...
No se, supongo que ya lo has contemplado, pero es lo único que se me ocurre...
bitrider
21/03/2006, 18:17
Quote ----------------------------------------
Cada dirección de memoria constará de 4 bytes, ¿no? Entonces, tendríamos 0x4000 direcciones, ¿o estoy yo equivocado?
----------------------------------------------
Sí, una dirección de memoria en la GP2x está compuesta de 4 bytes, 32bits.
No, no son cuatro dígitos en hexadecimal, sino 8. (0x00000000-0xffffffff).
El procesador principal de la GP2x, tiene MMU, Linux la usa. Con lo que tienes una dirección virtual que puede o no conincidir con una dirección de memoria física.
Por decir algo, no me he mirado mucho el código (perro que es uno), podría ser que no tuvieses alojada la memoria a la que intentas acceder y por lo tanto te peta.
Editado: la máxima dirección FÍSICA válida (excluidos registros especiales del procesador) con los 64MB de la GP2x sería 0x3ffffff. El rango virutal a signado a cada proceso depende del kernel de Linux.
Saludos.
Jan_Europa
22/03/2006, 04:26
aver Puck:
¿que juego estas portando?:
- ¿Rise of the Triad?
- ¿Heretic / Hexen?
.... jajaja, es que yo NO HE CONSEGUIDO compilar
esta función que está en casi TODOS los códigos pasados
a SDL de juegos de esa época
me llevo partiendo el pecho con el Rise of The Triad desde hace
més y medio :mad: (tiempo real de trabajo: unos dias sueltos de
fin de semana)y he conseguido avanzar hasta casi cargar los wads
y la pantalla, pero me petó otra de las reservas de memoria y no
he tenido tiempo de ponerme a mirarlo, pero no lo he dejado
(ya lo tengo que conseguir por mis coj...)
P.D: he intentado trampearlo pasado otros punteros y demás y
naaa....
el código está en el hexen y el heretic tal cual, el NK sabrá
algo
¿Como usas el GDB? me vendría bien porque voy a pegando
palos de ciego.... además es raro ya que el programa reserva
bloques enteros de memoria y los objetos se crean enteros
dentro de esos bloques... me huele a problema del compilador
Puck2099
22/03/2006, 04:38
aver Puck:
¿que juego estas portando?:
- ¿Rise of the Triad?
- ¿Heretic / Hexen?
Pues, como puse en mi web, se trata del Rise of the Triad, sí.
.... jajaja, es que yo NO HE CONSEGUIDO compilar
esta función que está en casi TODOS los códigos pasados
a SDL de juegos de esa época
me llevo partiendo el pecho con el Rise of The Triad desde hace
més y medio :mad: (tiempo real de trabajo: unos dias sueltos de
fin de semana)y he conseguido avanzar hasta casi cargar los wads
y la pantalla, pero me petó otra de las reservas de memoria y no
he tenido tiempo de ponerme a mirarlo, pero no lo he dejado
(ya lo tengo que conseguir por mis coj...)
P.D: he intentado trampearlo pasado otros punteros y demás y
naaa....
el código está en el hexen y el heretic tal cual, el NK sabrá
algo
Bueno, ese problema ya lo he pasado usando los defines para sparc y asegurándome de que alinee bien la memoria, pero ahora estoy con otro problema (supongo que será donde te encuentras tú también), que dan problemas las tablas o algo así.
¿Como usas el GDB? me vendría bien porque voy a pegando
palos de ciego.... además es raro ya que el programa reserva
bloques enteros de memoria y los objetos se crean enteros
dentro de esos bloques... me huele a problema del compilador
Pues entro en la consola por terminal a través del USB-serie y desde ella lanzo el gdb para ARM pasándole el ejecutable como argumento.
¿Qué problema te da el gdb?
Saludos
Jan_Europa
22/03/2006, 06:17
eps, ahora de instalarme el Fedora Core 5
y tengo que volver a cargar el toolchain y eso...
tardaré un poco y probaré lo del GDB, muchas gracias
a mi se me traba cuando recolocaba memoria con el z_malloc
y el z_realloc, del módulo dosutils.c / rt_util.c pero creo que lo conseguí arreglar.... y se me trababa en otro sitio
miraré a ver lo de los #defines esos
hermes PS2R
25/03/2006, 20:37
Y digo yo (a riesgo de parecer estúpido)... ¿no podría ocurrir que base->next (y por tanto new->next) estuviese sin inicializar y contenga basura? Eso explicaría que se apunte a una zona "indefinida", digamos...
No se, supongo que ya lo has contemplado, pero es lo único que se me ocurre...
Esa parece ser la razón mas evidente, pero existe otra posibilidad: que la direccion pasada no esté alineada a 4 bytes y al asignarle un valor de 32 bits de ese error.
Eso puede pasar porque en la definicion del struct pongamos algo asi:
struct
{
int a;
char b;
int c;
...
El elemento c no estaría alineado a 32 bits y provocaría un fallo.
Cuando se usa un struct como puntero, hay que tener cuidado con el tamaño total. Por ejemplo, si utilizaramos algo tal que asi;
typedef struct
{
int a;
int b;
char c;
} DATAS;
DATAS *dat=DIR;
Pues bien, si DIR estuviera alineada a 4 bytes y accedieramos
a los elementos dat->a, dat->b y dat->c, lo hariamos correctamente pero si hacemos dat++; (incrementamos el puntero con el size al hacer esto) al acceder al elemento a la direccion ya no estaria alineada a 4 bytes!
El compilador tiene una forma generica de adaptarse a estas situaciones para por ejemplo, sustituir una lectura de un valor de 4 bytes (un int) por varias lecturas de 1 byte.
En los procesadores x86 esto no es necesario pues la CPU puede hacer este tipo de lecturas/escrituras desalineadas, pero en nuestro caso podemos añadir #pragma al inicio de nuestros ficheros c para especificar el tipo de alineacion que queremos usar.
Así #pragma 1 debería resolver todos estos problemas y es la prueba que aconsejo para detectar este tipo de fallos (el codigo será mas lento, pero funcionará)
Con #pragma 0 se desactivaría esa alineación. Existe tambien la posibilidad de asignar el atributo 'packed' en las definiciones de estructuras de los compiladores GNU (pero me parece que no va con los compiladores que tenemos) pero lo mejor es ordenar bien los campos para garantizar la alineacion de los campos y añadir campos nuevos si es necesario, aunque queden sin uso. Ejemplo:
struct
{
int a; //+0 esto deberia estar alineado a 4 bytes, claro
char b; //+4
char pad[3];
int c; //+8, está alineado a 4 bytes ;)
} /* tamaño= 12 bytes, si esto fuera un puntero y lo incrementamos, conservaría la alineacion a 4 bytes */
Powered by vBulletin® Version 4.2.5 Copyright © 2026 vBulletin Solutions Inc. All rights reserved.