Разработка программ с несколькими нитями, которые проверяют и изменяют объекты библиотеки нитей
Библиотека отладки нитей (libpthdebug.a) содержит ряд функций, позволяющих приложениям проверять и изменять объекты библиотеки нитей.
Эта библиотека применяется как для 32-разрядных, так и для 64-разрядных приложений. Она обеспечивает поддержку нескольких нитей. Библиотека отладки нитей содержит 32-разрядный общий объект.
Библиотека отладки нитей предоставляет приложениям доступ к информации, хранящейся в библиотеке нитей. К такой информации относятся сведения о нитях, их атрибутах, взаимных блокировках, атрибутах блокировок, условных переменных, атрибутах условных переменных, блокировках чтения и записи, атрибутах этих блокировок, а также сведения о состоянии библиотеки нитей.
Библиотека отладки нитей не сообщает сведения о взаимных блокировках и их атрибутах, переменных условия, атрибутах этих переменных, блокировках чтения-записи и атрибутах этих блокировок, для которых параметр pshared равен PTHREAD_PROCESS_SHARED.
Инициализация
Приложение должно инициализировать библиотеку отладки нитей для каждого процесса с несколькими нитями. После загрузки процесса с несколькими нитями в нем должна быть вызвана функция pthdb_sessison_init. Библиотека отладки нитей поддерживает только один сеанс для каждого процесса. Приложение должно присвоить уникальный идентификатор пользователя и передать его в функцию pthdb_session_init, которая, в свою очередь, должна присвоить уникальный идентификатор сеансу. Этот идентификатор передается в качестве первого параметра всем остальным функциям библиотеки отладки нитей, за исключением pthdb_session_pthreaded. Когда библиотека отладки нитей запускает функцию обратного вызова, она передает приложению выделенный им идентификатор пользователя. Функция pthdb_session_init проверяет список функций обратного вызова, предоставляемых приложением, и инициализирует структуры данных сеанса. Кроме того, эта функция устанавливает флаги сеанса. Приложение должно передать флаг PTHDB_FLAG_SUSPEND функции pthdb_session_init. Полный список флагов приведен в описании функции pthdb_session_setflags.
Функции обратного вызова
- read_data
- Получает информацию из объекта pthread library
- alloc
- Выделяет память в библиотеке отладки нитей
- realloc
- Изменяет объем памяти, выделенный в библиотеке отладки нитей
- dealloc
- Освобождает память, выделенную в библиотеке отладки нитей
- read_regs
- Применяется только функциями pthdb_pthread_context и pthdb_pthread_setcontext
- write_data
- Применяется только функцией pthdb_pthread_setcontext
- write_regs
- Применяется только функцией pthdb_pthread_setcontext
Функция обновления
При каждой остановке приложения после инициализации сеанса необходимо вызывать функцию pthdb_session_update. Эта функция устанавливает или обновляет списки нитей, атрибутов нитей, взаимных блокировок, атрибутов взаимных блокировок, переменных условия, атрибутов этих переменных, блокировок чтения/записи, атрибутов этих блокировок, ключей отдельных нитей и активных ключей. Память для списков выделяется с помощью функций обратного вызова.
Функции работы с контекстом
Для получения контекстной информации служит функция pthdb_pthread_context, а для ее задания - функция pthdb_pthread_setcontext. Функция pthdb_pthread_context считывает контекст пользовательской нити из структуры данных нити ядра или пользовательской нити. Эта структура данных расположена в адресном пространстве приложения. Если пользовательская нить не связана с нитью ядра, контекстная информация считывается из библиотеки нитей. Если пользовательская нить связана с нитью ядра, необходимая информация считывается из приложения с помощью функций обратного вызова. При этом приложение должно определить, работает ли нить ядра в режиме ядра или пользовательском режиме, и выдать информацию для соответствующего режима.
Если пользовательская нить связана с нитью ядра, находящейся в режиме ядра, то нельзя считать полную информацию о контексте для пользовательского режима, так как ядро хранит ее компоненты в разных местах. Часть этой информации можно получить с помощью функции getthrds, так как она всегда сохраняет стек пользовательского режима. Приложение может получить доступ к этой информации, проверив значение thrdsinfo64.ti_scount. Если оно отлично от нуля, значит в структуре thrdsinfo64.ti_ustk находится стек пользовательского режима. С помощью стека пользовательского режима можно определить регистр адреса команды (IAR) и страницы функций обратного вызова, но нельзя узнать значения других регистров. Определение структуры thrdsinfo64 содержится в файле procinfo.h.
Функции списка
Библиотека отладки нитей управляет списками нитей, атрибутов нитей, взаимных блокировок, атрибутов взаимных блокировок, переменных условия, атрибутов переменных условия, блокировок чтения/записи, атрибутов блокировок чтения/записи, ключей отдельных нитей и активных ключей, представленных в виде ссылок соответствующих типов. Функции вида pthdb_объект возвращают указатель на следующий элемент соответствующего списка, где объект может принимать значение pthread, attr, mutex, mutexattr, cond, condattr, rwlock, rwlockattr или key. Если список пуст или достигнут конец списка, возвращается значение PTHDB_INVALID_ОБЪЕКТ, где ОБЪЕКТ - это PTHREAD, ATTR, MUTEX, MUTEXATTR, COND, CONDATTR, RWLOCK, RWLOCKATTR или KEY.
Функции работы с полями
Дополнительную информацию об объекте можно получить с помощью соответствующих функций работы с элементами объекта. Они имеют вид pthdb_объект_поле, где объект - это pthread, attr, mutex, mutexattr, cond, condattr, rwlock, rwlockattr или key, а поле - имя поля с дополнительной информацией об объекте.
Настройка сеанса
Приложение может изменить флаги сеанса с помощью функции pthdb_session_setflags. Эти флаги определяют количество регистров, считываемых и записываемых при работе с контекстом.
Текущие флаги сеанса можно получить с помощью функции pthdb_session_flags.
Завершение сеанса
В конце сеанса необходимо освободить память, выделенную под структуры данных сеанса, и удалить данные сеанса. Это можно сделать с помощью функции pthdb_session_destroy, которая освобождает память посредством функции обратного вызова. Эта функция освобождает всю память, которая была получена функциями pthdb_session_init и pthdb_session_update.
Пример подключения к библиотеке отладки нитей
/* директивы include */
#include <thread.h>
#include <ys/pthdebug.h>
...
int my_read_data(pthdb_user_t user, pthdb_symbol_t symbols[],int count)
{
int rc;
rc=memcpy(buf,(void *)addr,len);
if (rc==NULL) {
fprintf(stderr,&odq;Error message\n&cdq;);
return(1);
}
return(0);
}
int my_alloc(pthdb_user_t user, size_t len, void **bufp)
{
*bufp=malloc(len);
if(!*bufp) {
fprintf(stderr,&odq;Error message\n&cdq;);
return(1);
}
return(0);
}
int my_realloc(pthdb_user_t user, void *buf, size_t len, void **bufp)
{
*bufp=realloc(buf,len);
if(!*bufp) {
fprintf(stderr,“Сообщение об ошибке\n”);
return(1);
}
return(0);
}
int my_dealloc(pthdb_user_t user,void *buf)
{
free(buf);
return(0);
}
status()
{
pthdb_callbacks_t callbacks =
{ NULL,
my_read_data,
NULL,
NULL,
NULL,
my_alloc,
my_realloc,
my_dealloc,
NULL
};
...
rc=pthread_suspend_others_np();
if (rc!=0)
обработка ошибок
if (not initialized)
rc=pthdb_session_init(user,exec_mode,PTHDB_SUSPEND|PTHDB_REGS,callbacks,
&session);
if (rc!=PTHDB_SUCCESS)
обработка ошибок
rc=pthdb_session_update(session);
if (rc!=PTHDB_SUCCESS)
обработка ошибок
получить информацию об объекте pthread с помощью функций списка
и функций обработки полей
...
rc=pthread_continue_others_np();
if (rc!=0)
обработка ошибок
}
...
main()
{
...
}