Ho uno strano problema che non riesco a risolvere. Per favore aiuto!infinito abort() in un backrace di un core core del programma C++
Il programma è un'applicazione C++ multithread che gira su macchina ARM Linux. Recentemente ho iniziato a testare per le lunghe distanze e, a volte si blocca dopo 1-2 giorni in questo modo:
*** glibc detected ** /root/client/my_program: free(): invalid pointer: 0x002a9408 ***
Quando apro core dump vedo che il thread principale sembra ha uno stack danneggiato: tutto quello che posso vedere è infinito abort() chiamate.
GNU gdb (GDB) 7.3
...
This GDB was configured as "--host=i686 --target=arm-linux".
[New LWP 706]
[New LWP 700]
[New LWP 702]
[New LWP 703]
[New LWP 704]
[New LWP 705]
Core was generated by `/root/client/my_program'.
Program terminated with signal 6, Aborted.
#0 0x001c44d4 in raise()
(gdb) bt
#0 0x001c44d4 in raise()
#1 0x001c47e0 in abort()
#2 0x001c47e0 in abort()
#3 0x001c47e0 in abort()
#4 0x001c47e0 in abort()
#5 0x001c47e0 in abort()
#6 0x001c47e0 in abort()
#7 0x001c47e0 in abort()
#8 0x001c47e0 in abort()
#9 0x001c47e0 in abort()
#10 0x001c47e0 in abort()
#11 0x001c47e0 in abort()
E va avanti e avanti. Ho cercato di arrivare fino in fondo spostando la pila: frame 3000 o anche più, ma alla fine il core dump non ha più frame e non riesco ancora a capire perché sia successo.
Quando esamino gli altri thread, tutto sembra normale lì.
(gdb) info threads
Id Target Id Frame
6 LWP 705 0x00132f04 in nanosleep()
5 LWP 704 0x001e7a70 in select()
4 LWP 703 0x00132f04 in nanosleep()
3 LWP 702 0x00132318 in sem_wait()
2 LWP 700 0x00132f04 in nanosleep()
* 1 LWP 706 0x001c44d4 in raise()
(gdb) thread 5
[Switching to thread 5 (LWP 704)]
#0 0x001e7a70 in select()
(gdb) bt
#0 0x001e7a70 in select()
#1 0x00057ad4 in CSerialPort::read (this=0xbea7d98c, string_buffer=..., delimiter=..., timeout_ms=1000) at CSerialPort.cpp:202
#2 0x00070de4 in CScanner::readResponse (this=0xbea7d4cc, resp_recv=..., timeout=1000, delim=...) at PidScanner.cpp:657
#3 0x00071198 in CScanner::sendExpect (this=0xbea7d4cc, cmd=..., exp_str=..., rcv_str=..., timeout=1000) at PidScanner.cpp:604
#4 0x00071d48 in CScanner::pollPid (this=0xbea7d4cc, mode=1, pid=12, pid_str=...) at PidScanner.cpp:525
#5 0x00072ce0 in CScanner::poll1 (this=0xbea7d4cc)
#6 0x00074c78 in CScanner::Poll (this=0xbea7d4cc)
#7 0x00089edc in CThread5::Thread5Poll (this=0xbea7d360)
#8 0x0008c140 in CThread5::run (this=0xbea7d360)
#9 0x00088698 in CThread::threadFunc (p=0xbea7d360)
#10 0x0012e6a0 in start_thread()
#11 0x001e90e8 in clone()
#12 0x001e90e8 in clone()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(classi e funzioni nomi sono un po 'strano, perché li ho cambiato - :) Quindi, filo # 1 è dove lo stack è corrotto, backtrace di ogni altro (2-6) mostra
Backtrace stopped: previous frame identical to this frame (corrupt stack?).
Succede perché i thread 2-6 sono stati creati nel thread # 1.
Il fatto è che non posso eseguire il programma in gdb perché funziona su un sistema embedded. Non riesco a utilizzare il server gdb remoto. L'unica opzione è esaminare i dump di core che si verificano non molto spesso.
Potrebbe per favore suggerire qualcosa che possa portarmi avanti con questo? (Forse qualcos'altro che posso estrarre dal core dump o forse in qualche modo fare alcuni hook nel codice per catturare abort() call).
UPDATE: Basile Starynkevitch suggerito per utilizzare Valgrind, ma risulta che è stato portato solo per ARMv7. Ho ARM 926 che è ARMv5, quindi non funzionerà per me. Ci sono alcuni sforzi per compilare valgrind per ARMv5 però: Valgrind cross compilation for ARMv5tel, valgrind on the ARM9
UPDATE 2: Impossibile far funzionare Electric Fence con il mio programma. Il programma utilizza C++ e pthreads. La versione di Efence che ho ottenuto, 2.1.13 si è bloccata in un posto arbitrario dopo che ho avviato un thread e ho provato a fare qualcosa di più o meno complicato (ad esempio per inserire un valore in un vettore STL). Ho visto persone menzionare alcune patch per Efence sul web ma non ho avuto il tempo di provarle. Ho provato questo sul mio PC Linux, non su ARM, e altri strumenti come valgrind o Dmalloc non riportano alcun problema con il codice. Quindi, tutti quelli che usano la versione 2.1.13 di efence si preparano ad avere problemi con i pthread (o forse con pthread + C++ + STL, non so).
Sembra essere una buona ragione per usare 'valgrind' (che è stato recentemente portato su ARM, IIRC). http://valgrind.org/ –
Grazie per il suggerimento! Non sapevo che era stato portato su ARM –
Si è scoperto che valgrind è stato portato solo per ARM v7. Ho un processore ARM 926 e il mio compilatore si rifiuta di costruirlo :( –