[C con Clase] Que problemas puede causar memcpy al introducir un buffer de datos en un struct

marta vic marvicekl en gmail.com
Jue Oct 25 10:01:38 CEST 2012


Yo tengo un programa en c que se ejecuta con KLEE
KLEE lo que hace es de forma automatica obtener casos de prueba,
Te adjunto un ejemplo sencillo, y este ejemplo mas complejo para que veas
como puede variar

Muchas gracias por la ayuda, la verdad que al principio me costo incluso
encontrar esta solucion y cuando la encontre decidi que me quedaba con esto.
Pero si tienes una idea mejor me vendria genial.

Un saludo
Marta
___________________________________________________________________________

*1 Este es el ejemplo de un fichero de datosde klee*
 en realidad producira muchos ficheros como este (en concreto creo que los
datos de este caso no se corresponen exacatamente con los que te muestro
luego, si son las mismas estructuras, pero creo que no corresponde el valor
que introduzco luego.



ktest file : 'klee-last/test000005.ktest'
args       : ['wrapper_syncs.o']
num objects: 5
object    0: name: 'selection'
object    0: size: 4
object    0: data: 1
object    1: name: 'state_8'
object    1: size: 4
object    1: data: 0
object    2: name: 'state_20'
object    2: size: 484
object    2: data:
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
object    3: name: 'state_24'
object    3: size: 8
object    3: data: '\x00\x00\x00\x00\x00\x00\x00\x00'
object    4: name: 'state_28'
object    4: size: 28
object    4: data:
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'



_____________________________________________

Un ejemplo de como lo intrudiciria seria:
(aunque no se corresponden los datos con los del ejemplo anterior, si se
corresponden las estructuras)

*2 Las estructuras en este caso serian: en el mismo orden que se introducen
posteriormente*

typedef struct {int pos_offset;} MyModule_tc3_controller_state_t;

typedef struct {int drivemode;
int speed_arr[20];
int steering_arr[10][10];} MyModule_guidance_state_t;

typedef struct {int dir;
int angle;} MyModule_panning_controller_state_t;

typedef struct {int state;
int counter;
int angle;
signed int edge_start_angle;
signed int edge_end_angle;
signed int distance;
signed int heading;}

________________________________

*3 INTRODUCCION DE LOS DATOS: Como se puede ver arriba, klee va a producir
la info del tamaño de la estructura y yo voy a saber a que estructura se
corresponde.*
*
*
 value_state = 0;
memcpy(&MyModule_autonomous_car_tc3_cntrl_inst_state,&value_state,4);
memcpy(&
MyModule_guidance_system_g_inst_state,"\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",484);
memcpy(&MyModule_targeting_system_pc_inst_state,"\x00\x00\x00\x00\x00\x00\x00\x00",8);
memcpy(&MyModule_targeting_system_bd_inst_state,"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",28);


El 25 de octubre de 2012 00:06, José Luis Torre <
joseluistorrehernandez en gmail.com> escribió:

> Marta:
>
> Muéstrame un ejemplo de la salida del programa KLEE y te comentaré cómo
> puedes leerlo desde tu programa.
>
> Saludos
> José Luis
>
>
> El 24 de octubre de 2012 22:26, marta vic <marvicekl en gmail.com> escribió:
>
> Muchisimas gracias por las respuestas
>>
>> La cuestion es que yo recibo ese valor de otro programa y lo tengo que
>> introducir en un programa c para inicializar la estructura,
>> el programa (KLEE) me da directamente esa informacion y la estructura
>> siempre sera la adecuada, pro qeu es la misma estructura que klee ha
>> analizado y me ha dado ese valor hexadecimal.
>>
>> por lo tanto necesito una forma de re introducir el valor en la
>> estructura y no creo que con memset pueda hacerlo (aunque voy a mirar si
>> tengo alguna alternativa)
>>
>> Los valores de la salida seran distintos a 0, ya que lo que hace klee es
>> generar valores para las estructuras pero no es capaz de separarlos por
>> campos de ahi el problema
>>
>> muchisimas gracias
>> mirare la documentacion  que me aconsejas
>>
>> Un saludo
>> El 8 de octubre de 2012 12:03, Salvador Pozo <salvador en conclase.net>escribió:
>>
>> El pasado 2012-10-07 22:10:00, marta vic escribió:
>>>
>>> mv> Hola
>>> mv> Tengo una duda, y busco mas lugares donde pueda acceder a
>>> explicaciones o
>>> mv> documentacion que una explicacion concreta,
>>> mv> me gustaria definir los problemas que se pueden encontrar al intentar
>>> mv> ejecutar un codigo como este:
>>> mv> memcpy(&estructura1,"\x00\x00\x00\x00\x00\x00\x00\x00",8);
>>> mv> en este caso
>>> mv> estructura1{
>>> mv>     int a;
>>> mv>     int b;
>>> mv> }
>>>
>>> Hola:
>>>
>>> Antes de ver qué problemas puede haber en este mecanismo, comentar que
>>> existen soluciones mejores para hacer lo que se pretende.
>>>
>>> En la misma biblioteca que memcpy existe otra función, memset, que está
>>> diseñada específicamente para esa tarea.
>>>
>>> En tu caso concreto, podría usarse de este modo:
>>>
>>> ----8<------
>>> struct {
>>>     int a;
>>>     int b;
>>> } estructura1;
>>>
>>> memset(&estructura1,0,sizeof(structura1));
>>> ----8<------
>>>
>>> Esto tiene algunas ventajas evidentes:
>>> 1) No necesitas una cadena de ceros de longitud arbitraria, ya que
>>> usamos un único valor de tipo int, que se usará como un byte (un unsigned
>>> char).
>>> 2) No tenemos que usar una constante como tamaño de la estructura, en su
>>> lugar usamos en operador sizeof, que nos da el tamaño exacto de la
>>> estructura, independientemente de la arquitectura y de la alineación de
>>> bytes usada.
>>>
>>> Respondiendo a tu pregunta, ahora no puedo decirte un lugar donde puedas
>>> encontrar información sobre ese tema, sobre todo, porque no sé si existe
>>> algo tan concreto.
>>>
>>> Los problemas son, entre otros, los que ha indicado José Luis:
>>>
>>> - Dependiendo de la plataforma y del compilador, los valores enteros
>>> pueden tener distintos tamaños. En general, el tamaño de una estructura
>>> estará determinado por el tamaño de cada uno de sus componentes, y en C ese
>>> tamaño no está definido, salvo que el de int es mayor o igual que char, y
>>> el de long int mayor o igual que int. (
>>> http://c.conclase.net/curso/index.php?cap=002#inicio)
>>>
>>> - Otro problema es el de alineación de las variables en memoria. A
>>> menudo, para mejorar la eficacia de los procesadores a la hora de acceder a
>>> memoria, las direcciones de las variables pueden ser múltiplos de 2, de 4 o
>>> de 8, dependiendo del tamaño de la palabra del microprocesador.
>>> (http://c.conclase.net/curso/index.php?cap=011b#inicio)
>>>
>>> Por ejemplo, en esta estructura:
>>> struct A {
>>>    int x;
>>>    char a;
>>>    int y;
>>>    char b;
>>> };
>>>
>>> Si el alineamiento es de cuatro bytes, las posiciones de memoria de cada
>>> elemento del array no serán consecutivas:
>>> 0-3: x
>>> 4: a
>>> 5-7: libre
>>> 8-11: y
>>> 12: b
>>> 13-15: libre
>>>
>>> De este modo, una estructura que debería ocupar 10 bytes, en realidad
>>> ocupa 16.
>>>
>>> Es más, el tamaño final puede depender del orden en que se declaran los
>>> elementos de la estructura, y de si se activa o no el alineamiento de bytes.
>>>
>>> - El problema con el formato Big Endian o Little Endian, en el caso
>>> concreto de inicializar con ceros, no tiene importancia. Otro tema sería si
>>> los valores iniciales no fueran nulos.
>>>
>>> - Por último, los problemas son casi iguales si se trata de arrays o
>>> estructuras. En los dos casos nos afecta la arquitectura y el problema del
>>> alineamiento de bytes.
>>>
>>> En cuanto a soluciones, arriba te he comentado la que se suele usar en
>>> C, que consiste en utilizar la función memset.
>>>
>>> En C++ es preferible usar constructores, al menos en el caso de
>>> estructuras, ya que para los arrays puede interesar más usar memset también.
>>>
>>> En general, no es buena idea que el programador haga las cuentas si
>>> puede hacer que las haga el compilador. Para hacer las cuentas a mano, como
>>> en tu ejemplo, debemos asumir el tamaño de las variables y cierta
>>> alineación, pero eso hace que el programa no sea transportable, y no
>>> podemos garantizar que funcione correctamente si se compila en otra
>>> plataforma, con otro sistema operativo o con otro compilador.
>>>
>>> Seguramente encuentres documentación en la red haciendo consultas con:
>>> memcpy gibendian
>>> memcpy alineamiento bytes
>>> memcpy plataformas
>>>
>>> Suerte, y hasta pronto.
>>>
>>> --
>>> Salvador Pozo (Administrador)
>>> mailto:salvador en conclase.net
>>> _______________________________________________
>>> Lista de correo Cconclase Cconclase en listas.conclase.net
>>> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
>>> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>>>
>>
>>
>> _______________________________________________
>> Lista de correo Cconclase Cconclase en listas.conclase.net
>> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
>> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>>
>
>
>
> --
> José Luis Torre
> ww.ehu.es
>
>
>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20121025/d12238b1/attachment.html>
------------ próxima parte ------------
ktest file : 'klee-last/test000001.ktest'
args       : ['wrapper.o']
num objects: 2
object    0: name: 'selection'
object    0: size: 4
object    0: data: 0
object    1: name: 'state_6'
object    1: size: 8
object    1: data: '\x00\x00\x00\x00\x00\x00\x00\x00'

ktest file : 'klee-last/test000002.ktest'
args       : ['wrapper.o']
num objects: 2
object    0: name: 'selection'
object    0: size: 4
object    0: data: 1
object    1: name: 'state_6'
object    1: size: 8
object    1: data: '\x00\x00\x00\x00\x00\x00\x00\x00'

ktest file : 'klee-last/test000003.ktest'
args       : ['wrapper.o']
num objects: 2
object    0: name: 'selection'
object    0: size: 4
object    0: data: 1
object    1: name: 'state_6'
object    1: size: 8
object    1: data: '\x00\x00\x00\x00\x02\x00\x00\x00'
------------ próxima parte ------------
A non-text attachment was scrubbed...
Name: gencode_6_test_0_enviar.h
Type: text/x-chdr
Size: 608 bytes
Desc: no disponible
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20121025/d12238b1/attachment.bin>


Más información sobre la lista de distribución Cconclase