Вы можете использовать несколько потоков для отслеживания приложения? - PullRequest
8 голосов
/ 18 июня 2009

Я пишу ориентированный на GUI отладчик, который ориентирован в первую очередь на Linux, но я планирую порты для других ОС в будущем. Поскольку графический интерфейс должен всегда оставаться интерактивным, у меня есть несколько потоков, обрабатывающих разные вещи.

Прежде всего, у меня есть поток "событие отладки", который просто зацикливается на ожидании возврата waitpid и доставляет полученные события другим потокам. Я делаю это потому, что у waitpid нет тайм-аута, что делает его очень трудным интегрировать его с другими циклами событий и поддерживать отзывчивость (waitpid может зависать бесконечно!).

Эта стратегия до сих пор прекрасно работала для сборок Linux. В последнее время я пытался информировать мой поток отладчика (как в потоках отлаживаемого приложения, а не в самом отладчике).

Поэтому я установил параметры ptrace для отслеживания событий клонирования и поиска состояния, для которого верхний 16-разрядный бит установлен на PTRACE_EVENT_CLONE. Затем я использую PTRACE_GETEVENTMSG, чтобы получить TID нового потока. Все это прекрасно работает в моих маленьких приложениях для тестирования. Но по какой-то причине он терпит неудачу, когда я помещаю этот код в свой настоящий отладчик. (Я получаю код ошибки «Нет такого процесса»)

Единственное, что мне пришло в голову, это то, что в Windows есть правило, что только поток, прикрепленный к приложению, может прослушивать события отладки. Есть ли у Linux ptrace подобное ограничение? Если так, почему мой код работает для других событий отладки?

EDIT:

Похоже, что по крайней мере waitpid поддерживает ожидание из другого потока, на странице руководства написано:

До Linux 2.4 поток был просто частный случай процесса, и как следствие одна нить не могла дождаться дети из другого потока, даже когда последний принадлежит той же теме группа. Тем не менее, POSIX предписывает такая функциональность, а с Linux 2.4 а нить может и по умолчанию будет ждать детей других темы в одной группе.

Так что самое большее это ограничение ptrace.

Ответы [ 2 ]

5 голосов
/ 08 декабря 2009

У меня была та же проблема (плюс много других!) При реализации специфичной для Linux части Maxine VM отладчика VM . Вы правы в том, что только один поток в отладчике может использовать ptrace для управления отладчиком. Мы достигаем этого, делая все вызовы ptrace в выделенном потоке. Возможно, вам будет полезно посмотреть файлы LinuxTask.java, linuxTask.h и linuxTask.c в источниках Maxine, доступных по адресу kenai.com/projects/maxine/sources/maxine/show

.
4 голосов
/ 11 июля 2009

Насколько я могу судить, это запрещено. Задача не может использовать ptrace для задачи, к которой она не прикреплена. Кроме того, задача может быть отслежена не более чем одной другой задачей, поэтому вы не можете просто присоединить ее один раз в каждом потоке. Я думаю, это потому, что когда одна задача присоединяется к другой, задача трассировки становится родительской для отслеживаемой задачи, и у каждой задачи может быть только один родительский элемент.

Кажется, что многопотоковая трассировка должна быть разрешена, потому что потоки являются частью одного и того же процесса, но с точки зрения реализации на самом деле нет большого различия между потоками и процессами в ядре Linux. Поток - это просто задача, которая разделяет большую часть своих ресурсов с другой задачей.

Если вам интересно, вы можете просмотреть исходный код для ptrace в ядре. В частности, посмотрите на ptrace_check_attach, который вызывается sys_ptrace для большинства запросов. Он возвращает -ESRCH (звучит как код ошибки, который вы получаете), если родительский объект целевой задачи не является текущей задачей.

...