2010-02-20 4 views
11

que han estado tratando de depurar un bloqueo en mi aplicación que bloquea (es decir, afirma un * * glibc detectado libre(): puntero no válido: 0x000000000070f0c0 ***) mientras trato de hacer una asignación simple a una cadena. Tenga en cuenta que estoy compilando en un sistema Linux con gcc 4.2.4 con un nivel de optimización configurado en -O2. Con -O0, la aplicación ya no se bloquea.C++ programa siempre se bloquea al hacer un std :: string asignar

E.g.

std::string abc; 

abc = "testString"; 

pero si he cambiado el código de la siguiente manera que ya no se bloquea

std::string abc("testString"); 

Así que de nuevo me rasqué la cabeza! Pero el patrón interesante fue que el bloqueo se movió más tarde en la aplicación, OTRA VEZ en otra cadena. Me pareció raro que la aplicación se bloquee continuamente en una asignación de cadena. Una traza típica accidente se vería de la siguiente manera:

#0 0x00007f2c2663bfb5 in raise() from /lib64/libc.so.6 
(gdb) bt 
#0 0x00007f2c2663bfb5 in raise() from /lib64/libc.so.6 
#1 0x00007f2c2663dbc3 in abort() from /lib64/libc.so.6 
#2 0x00000000004d8cb7 in people_streamingserver_sighandler (signum=6) at src/peoplestreamingserver.cpp:487 
#3 <signal handler called> 
#4 0x00007f2c2663bfb5 in raise() from /lib64/libc.so.6 
#5 0x00007f2c2663dbc3 in abort() from /lib64/libc.so.6 
#6 0x00007f2c26680ce0 in ??() from /lib64/libc.so.6 
#7 0x00007f2c270ca7a0 in std::string::assign (this=0x7f2c21bc8d20, __str=<value optimized out>) 
    at /home/bbazso/ThirdParty/sources/gcc-4.2.4/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:238 
#8 0x00007f2c21bd874a in PEOPLESProtocol::GetStreamName (this=<value optimized out>, 
    pRawPath=0x2342fd8 "rtmp://127.0.0.1/mp4:pop.mp4", [email protected]) 
    at /opt/trx-HEAD/gcc/4.2.4/lib/gcc/x86_64-pc-linux-gnu/4.2.4/../../../../include/c++/4.2.4/bits/basic_string.h:491 
#9 0x00007f2c21bd9daa in PEOPLESProtocol::SignalProtocolCreated (pProtocol=0x233a4e0, [email protected]) 
    at peoplestreamer/src/peoplesprotocol.cpp:240 

Este era un comportamiento muy raro y por lo que comenzó a hurgar más en mi solicitud para ver si había algún tipo de corrupción de memoria (ya sea montón o pila) de error que podría estar ocurriendo que podría estar causando este extraño comportamiento. Incluso verifiqué la corrupción del ptr y salí con las manos vacías. Además de la inspección visual del código también probé las siguientes herramientas:

  • Valgrind utilizando tanto memcheck y exp-ptrcheck
  • cerca eléctrica
  • libsafe
  • compilé con -fstack-protector-all en gcc
  • probé MALLOC_CHECK_ establece en 2
  • me encontré con mi código a través de cheques de pelusa, así como cppcheck (para comprobar si hay errores)
  • Y yo s atravesó el código usando gdb

Así que probé muchas cosas y seguí con las manos vacías. Así que me preguntaba si podría ser algo así como un problema de vinculador o un problema de biblioteca de algún tipo que podría estar causando este problema. ¿Hay algún problema conocido con std :: string que haga que sea susceptible de bloquearse en -O2 o tal vez no tenga nada que ver con el nivel de optimización? Pero el único patrón que puedo ver hasta ahora en mi problema es que siempre parece bloquearse en una cadena y me preguntaba si alguien sabía de algún problema que pudiera estar causando este tipo de comportamiento.

¡Muchas gracias!

+0

¿Y valgrind no dice nada? ¿Puedes dar más detalles sobre la distribución libc, libstdC++, kernel y Linux? – LiraNuna

+0

Puede mostrar esto: VANSProtocol :: GetStreamName y esto: VANSProtocol :: SignalProtocolCreated? – Tom

+0

¿Puedes probar un GCC más nuevo? – AndiDog

Respuesta

7

¿Se puede repetir el bloqueo con un programa básico de dos líneas?

#include <string> 

int main() 
{ 
    std::string abc; 
    abc = "testString"; 
} 

Si eso falla, publique sus opciones exactas de compilación/enlace?

De lo contrario, comience a desagregar su código. Elimine las líneas de las líneas un puñado a la vez hasta que desaparezca el error. Una vez que tenga otro cambio que puede agregar para causar el bloqueo y eliminarlo para que desaparezca, eso debería ayudarlo a localizar el problema.

+0

Probé exactamente eso, con -O2 y -O0 y nada. – Tom

+2

@Tom - está bien, así que tome mi próxima recomendación. Comience a reducir el resto del código hasta que la asignación ya no se bloquee. –

10

Esta es una suposición inicial usando toda la información que puedo extraer de su rastro posterior.

Lo más probable mezclando y combinando versión de gcc, enlazador y libstdC++ que da como resultado un comportamiento inusual en el equipo host:

  1. libc es el sistema de: /lib64/libc.so.6
  2. libstdC++ está en un directorio "Terceros" - se trata de sospechas, ya que me dice que podría ser compilado en otro lugar con un objetivo diferente - /home/bbazso/ThirdParty/sources/gcc-4.2.4/x86_64-pc-linux-gnu/libstdc++-v3/
  3. Sin embargo, otro libstdC++ en /opt: /opt/trx-HEAD/gcc/4.2.4/lib/gcc/x86_64-pc-linux-gnu/4.2.4/../../../../include/c++/4.2.4/bits/basic_string.h:491

Además, GCC puede mezclar el ld del sistema en lugar de hacerlo a sí mismo, lo que puede causar un uso más extraño de mapas de memoria.

+3

+1. Tener 2 libstdC++ s (como sea que haya sucedido) parece ser la causa (o la causa) del problema. He tenido problemas para pasar std :: strings a través de DSO cuando uso la implementación de std :: string de GNU (hace algunas optimizaciones para la cadena vacía que puede causar problemas) sin las complicaciones adicionales de múltiples libstdC++ s. –

+0

También me pregunto cuál es el motivo para no usar el GCC nativo de la distribución. – LiraNuna

+0

¡Gracias! Esto parece una buena razón. Estoy en el medio de cambiar mi compilación para que solo use un gcc y será el de la distro nativa de Ubuntu gcc 4.2.4-5. Además, ¿podría profundizar más en las optimizaciones de una cadena vacía o dirigirme a un sitio que proporciona información sobre esto? Me interesa saber qué hace para una cadena vacía que puede causar este tipo de problema. ¡Gracias de nuevo! – bbazso

0

Como dijiste, es un comportamiento extraño.

Para ser sincero, creo que estás perdiendo el tiempo investigando un posible error con std :: strings. Las cadenas son perfectamente seguras, siempre y cuando las uses bien.

De todos modos, con la información que está dando: En primer lugar, ¿estás usando hilos? Puede ser un problema de hilo. En segundo lugar, verifica tu programa usando valgrind. ¿No tienes advertencias?

Nota: Las advertencias más importantes de valgrind son la lectura no válida y la escritura no válida.

PD: Como se ha dicho en el comentario, se debe utilizar probablemente g ++ para compilar código C++;)

0

pasó a mí debido a usar malloc para una clase que tenía std :: cadenas como miembros de datos. Difícil.

Cuestiones relacionadas