2012-07-04 3 views
3

Итак, у меня есть довольно существенная программа, которая периодически замерзает.
Эта программа использует Qt, открытый граф сцены и ведение журнала Google. Это замораживание происходит в середине печати в журнале Google. Сама программа печатает тонну отладочной информации. Я был в состоянии подключиться к программе через GDB-сервер и это трассировки стека:Замедление на __write_nocancel

#0 0x000000397ac0e030 in __write_nocancel() at ../sysdeps/unix/syscall-template.S:82 
#1 0x00007f5eecb74aeb in google::LogMessage::SendToLog()() from /lib64/libglog.so.0 
#2 0x00007f5eecb71fc7 in google::LogMessage::Flush()() from /lib64/libglog.so.0 
#3 0x00007f5eecb721a9 in google::LogMessage::~LogMessage()() from /lib64/libglog.so.0 
#4 0x00000000004874a6 in LSDB::process (this=0x242d918, lsp=0x25f9200, circuit=0x24c7af0) at ../src/model/trill/LSDB.cpp:481 
#5 0x00000000004a0f6f in Circuit::rx (this=0x24c7af0, eth=0x246fdf0) at ../src/model/trill/Circuit.cpp:355 
#6 0x000000000045c950 in Circuit::qt_static_metacall (_o=0x24c7af0, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7fffaade95a0) 
    at ../src/model/trill/Circuit.moc.cpp:55 
#7 0x000000398798cb9f in QMetaObject::activate (sender=0x2470140, m=<optimized out>, local_signal_index=<optimized out>, argv=0x7fffaade95a0) 
    at kernel/qobject.cpp:3547 
#8 0x0000000000459610 in FramePublisher::subscription (this=0x2470140, _t1=0x246fdf0) at ../src/model/system/FramePublisher.moc.cpp:98 
#9 0x000000000047c0d6 in FramePublisher::rx (this=0x2470140, frame=0x246fdf0) at ../src/model/system/FramePublisher.hpp:21 
#10 0x000000000047bedb in EthernetPort::rx (this=0x246d7a0, frame=0x25a4180) at ../src/model/system/EthernetPort.cpp:81 
#11 0x000000000045a208 in EthernetPort::qt_static_metacall (_o=0x246d7a0, _c=QMetaObject::InvokeMetaMethod, _id=1, _a=0x7fffaade9810) 
    at ../src/model/system/EthernetPort.moc.cpp:51 
#12 0x000000398798cb9f in QMetaObject::activate (sender=0x246d7a0, m=<optimized out>, local_signal_index=<optimized out>, argv=0x7fffaade9810) 
    at kernel/qobject.cpp:3547 
#13 0x0000000000459ddc in Port::rx (this=0x246d7a0, _t1=0x25a4180) at ../src/model/system/Port.moc.cpp:110 
#14 0x00000000004803a6 in Port::inject (this=0x246d7a0, frame=0x25a4180) at ../src/model/system/Port.cpp:25 

...

Обратите внимание на замораживание само по себе происходит в __write_nocancel. Существует только один поток работает ...

(GDB) Информация о нити Id Target Id Кадр
* 1 Thread 21507 0x000000397ac0e030 в __write_nocancel() в ../sysdeps/unix/syscall-template.S: 82

Любые идеи о том, что вызывает замораживание? Позвольте мне знать, что может помочь другая информация.

+1

Вы пишете что-нибудь особенное (сокет, файл на сервере nfs и т. Д.?) Я предлагаю вам запустить программу под valgrind, чтобы искать повреждение памяти, если возможно – nos

+0

Итак, я использую GLOG с GLOG_logtostderr = 1, что означает, что он будет записывать сообщения журнала в stderr. Из документации говорится, что она пропускает запись в файл, когда у вас установлен этот флаг. http://google-glog.googlecode.com/svn/trunk/doc/glog.html Я не вижу никаких проблем с valgrind, которые должны вызывать это. –

+0

Вы когда-нибудь узнавали, что это вызывает? –

ответ

1

Вы сказали, что вывод записывается в stderr. Если stderr не постоянно считывается отдельным процессом, буфер ввода-вывода может быть заполнен, поэтому он ожидает, что stderr будет считан, прежде чем он будет писать больше.

Если процесс A записывает в stderr, а процесс B обычно считывает из stderr, но в настоящее время ожидает процесса A, это может привести к блокировке. В вашем случае это может привести только к тупиковой ситуации, если запись в stderr слишком велика, поскольку меньшая запись будет успешной немедленно и свободным процессом A, тем самым освобождая процесс B от чтения с stderr.

Это некоторые предположения с моей стороны, но в целом я бы предположил, что ваша проблема в том, что вы ждете записи в полный буфер.

+0

В этом случае процесс В является терминалом, поэтому он не должен ждать моего процесса за все, что я могу себе представить. Если буфер записи заполнен, этот процесс должен уступить, и у терминала будет некоторое время для обработки того, что ему нужно. Спасибо за мысли. –

Смежные вопросы