Различные библиотеки C / C ++ разбивают друг друга;возможное вмешательство в poll () и select ()? - PullRequest
0 голосов
/ 08 октября 2018

Tl; dr

Каким-то образом асинхронные обратные вызовы из одной библиотеки обнаруживаются в стеке вызовов из другой библиотеки, даже если они не общаются напрямую друг с другом.Сбой происходит, когда одна библиотека вызывает select, в то время как другая имеет три потока, вызывающих poll.

Резюме

У меня есть проект, использующий функции двух сторонних библиотек.Они оба прекрасно работают в изоляции, но когда я помещаю их в одну и ту же программу, в ней возникают ошибки.Дело в том, что они не вызывают друг друга напрямую, но как-то стек показывает, что они есть.Оба полагаются на многопоточность и / или асинхронные обратные вызовы.

Цель

Я пытаюсь считать USB-камеру с закрытым исходным кодом C ++ Basler Pylon API .С помощью этой библиотеки вы - подключаетесь к физической камере, создавая экземпляр объекта InstantCamera.
- Затем вы можете вызвать InstantCamera::StartGrabbing(), чтобы запустить новый поток, который непрерывно загружает изображения во внутренний буфер FIFO.
- НаконецВы вызываете InstantCamera::RetrieveResult(int timeout, CGrabResultPtr& grabResult), чтобы поместить следующее изображение из очереди в CGrabResultPtr, который является объектом интеллектуального указателя.Этот вызов блокируется в течение timeout мс, если изображение еще не готово.

Я пытаюсь соединить это с более крупной системой сбора научных данных со многими другими инструментами, связывающимися с открытым исходным кодом C Среда сбора данных MIDAS .Как я уже писал, клиентская программа MIDAS, которая должна считывать изображения с камеры, выполняет: - При запуске создаёт экземпляр нового объекта InstantCamera и проверяет, что мы можем получить из него одно изображение.- Перейдите в цикл ожидания, который вызывает встроенную функцию MIDAS cm-yield, которая проверяет, были ли получены какие-либо сообщения, а затем бездействует в течение некоторого времени ожидания вызова RPC.

Проблема

Цикл холостого хода MIDAS является внутренним на 100%, и, тем не менее, если камера когда-либо считывалась, это вызывает сбой.Типичная обратная трассировка выглядит следующим образом:

Program terminated with signal 6, Aborted.
#0  0x00007f6de275a277 in __GI_raise (sig=sig@entry=6)>    
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56    return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);

(gdb) bt
#0  0x00007f6de275a277 in __GI_raise (sig=sig@entry=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007f6de275b968 in __GI_abort () at abort.c:90
#2  0x00007f6de30697d5 in __gnu_cxx::__verbose_terminate_handler() ()
    at ../../../../libstdc++-v3/libsupc++/vterminate.cc:95
#3  0x00007f6de3067746 in __cxxabiv1::__terminate(void (*)()) (handler=    <optimized out>) at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:38
#4  0x00007f6de3067773 in std::terminate() ()
    at ../../../../libstdc++-v3/libsupc++/eh_terminate.cc:48
#5  0x00007f6de3067993 in __cxxabiv1::__cxa_throw(void*, std::type_info*, void (*)(void*)) (obj=0x230e110, tinfo=0x7f6de6da58f0 <typeinfo for GenICam_3_0_Basler_pylon_v5_0::RuntimeException>, dest=0x7f6de6afdd6e <GenICam_3_0_Basler_pylon_v5_0::RuntimeException::~RuntimeException()>)
    at ../../../../libstdc++-v3/libsupc++/eh_throw.cc:87
#6  0x00007f6de6b38421 in Pylon::WaitObjectEx::Signal() ()
    at /opt/pylon5/lib64/libpylonbase-5.0.12.so
#7  0x00007f6de6fd26d0 in <signal handler called> () at /lib64/libpthread.so.0
#8  0x00007f6de2819c73 in select () at ../sysdeps/unix/syscall-template.S:81
#9  0x0000000000434ebe in ss_suspend (millisec=millisec@entry=100,     msg=msg@entry=0) at src/system.c:4075
#10 0x0000000000431855 in cm_yield (millisec=millisec@entry=100)
    at src/midas.c:5041
#11 0x0000000000417d77 in scheduler () at src/mfe.c:2564
---Type <return> to continue, or q <return> to quit---
#12 0x000000000040f67c in main (argc=<optimized out>, argv=<optimized out>)
    at src/mfe.c:2899

Как вы можете видеть, внутренний холостой цикл MIDAS прерывается функцией Pylon, даже если в этот момент они вообще не взаимодействуют в программе.Обратный след всех нитей показывает основной цикл холостого хода и 3 связанных с пилоном потока, все в функции poll().

Я ничего не знаю о poll и select, кроме того, что они связаны друг с другом и имеют какое-то отношение к праздной блокировке во время ожидания доступных данных.Они конечно кажутся подозрительными здесь.

Вопрос

Как я могу выяснить, что эти библиотеки делают друг с другом, что вызывает столько проблем?Или, более конкретно, есть ли способ изолировать эти библиотеки / вызовы, чтобы они перестали мешать?

У меня есть доступ к источнику MIDAS (цикл бездействия, вызывающий select), но не к коду pylon (3 потока, вызывающего poll).Редактирование источника MIDAS для целей отладки - это хорошо, но я бы хотел избежать его разветвления, если это возможно (если только это не настоящая ошибка, которую следует передавать в апстрим).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...