2012-04-17 14 views
7

Estoy trabajando con una gran biblioteca de C donde algunos índices de matriz se calculan usando int. Necesito encontrar una manera de atrapar desbordamientos enteros en el tiempo de ejecución de forma tal que se reduzca a una línea problemática de código. Libc manual indica:Detectar desbordamiento de enteros

FPE_INTOVF_TRAP Desbordamiento de enteros (imposible en un programa de C a menos que le permiten atrapar desbordamiento de un modo específico del hardware).

Sin embargo, la opción gcc -ffpe-trap sugiere que solo se aplican a los números FP?
Entonces, ¿cómo habilito la trampa de desbordamiento de enteros? Mi sistema es Xeon/Core2, gcc-4.x, Linux 2.6

He examinado las preguntas similares, pero todas se reducen a la modificación del código. Sin embargo, necesito saber qué código es problemático en primer lugar.
Si Xeons no puede atrapar desbordamientos, ¿qué procesadores pueden? También tengo acceso a máquinas que no son de emt64.

He encontrado una herramienta diseñada para llvm mientras tanto: http://embed.cs.utah.edu/ioc/ ¿No parece haber un equivalente para gcc/icc?

+0

Hasta donde yo sé, ningún procesador x86 admite el atrapamiento en el desbordamiento de enteros. Muchos RISC cpus do (al igual que power y sparc), así como antiguas CPUs de mini/mainframe (como VAX) –

+0

Podría probar Power, sin VAX por ahí. – Anycorn

Respuesta

3

Ok, puede que tenga que responder mi propia pregunta.

Encontré que gcc tiene -ftrapv opción, una prueba rápida confirma que al menos en mi sistema se produce un desbordamiento. Publicaré información más detallada a medida que aprendo más ya que me parece una herramienta muy útil.

+0

Vea también: http://stackoverflow.com/a/5005792/462335 – nibot

2

La aritmética de enteros sin signo no se desborda, por supuesto.

Con la aritmética de enteros con signo, el desbordamiento conduce a un comportamiento indefinido; Cualquier cosa podría pasar. Y los optimizadores se vuelven agresivos sobre la optimización de las cosas que se desbordan. Por lo tanto, su mejor opción es evitar el desbordamiento, en lugar de atraparlo cuando sucede. Considere usar el CERT 'Secure Integer Library' (la URL a la que se hace referencia parece haber desaparecido AWOL/404; no estoy seguro de lo que pasó aún) o la biblioteca 'Safe Integer Operation' de Google.

Si debe atrapar el desbordamiento, necesitará especificar qué plataforma le interesa (O/S, incluida la versión, compilador, incluida la versión), porque la respuesta será muy específica de la plataforma.

+1

Necesito saber * qué * operaciones reemplazar (con size_t). Especifiqué sistema/compilador en la pregunta. – Anycorn

2

¿Sabe exactamente en qué línea se está produciendo el desbordamiento? Si es así, es posible que pueda ver la bandera de llevar del ensamblador si la operación en cuestión causó un desbordamiento. Esta es la bandera que usa la CPU para hacer cálculos de números grandes y, aunque no está disponible en el nivel C, puede ayudarlo a resolver el problema, o al menos darle la oportunidad de hacer algo.

BTW, encontrado this enlace para gcc (-ftrapv) que habla de una trampa de enteros. Puede ser lo que estás buscando.

+0

no, el problema es encontrar dónde ocurre el desbordamiento – Anycorn

+2

¿Hay alguna posibilidad de que se caiga un punto de interrupción de escritura en memoria en el contador para ayudarlo? –

+0

No lo creo. Hay varios lugares donde 'int' se usa en lugar de' size_t', la depuración manual es muy difícil. Sin embargo, podría haber encontrado una solución. – Anycorn

0

Puede usar ensamblador en línea en gcc para usar una instrucción que podría generar un desbordamiento y luego probar el indicador de desbordamiento para ver si lo que realmente hace:

int addo(int a, int b) 
{ 
    asm goto("add %0,%1; jo %l[overflow]" : : "r"(a), "r"(b) : "cc" : overflow); 
    return a+b; 
overflow: 
    return 0; 
} 

En este caso, se trata de añadir a y b, y si lo hace, va a la etiqueta overflow. Si no hay desbordamiento, continúa, haciendo el agregado nuevamente y devolviéndolo.

Esto entra en la limitación de GCC de que un bloque de ASM en línea no puede generar un valor y tal vez una ramificación; si no fuera por eso, no necesitaría un segundo complemento para obtener realmente el resultado.

Cuestiones relacionadas