Я создал оболочки для функций pthread, используя dlopen и dlsym, чтобы отладить и профилировать некоторые проблемы, возникающие в моем приложении. Профилировщик проходит все юнит-тесты. К сожалению, похоже, что я обошел некоторую инициализацию библиотеки, потому что getenv теперь возвращает ноль для всех входных данных. Если я удалю профилировщик, вернется правильная операция getenv.
Я считаю, что проблема в том, что компилятор не связался в Libpthread, потому что он не видит символы, запрошенные из библиотеки во время ссылки. Я просмотрел исходный код glib, но не нашел очевидной функции инициализации во время выполнения, которую я могу загрузить и выполнить с помощью dlsym.
Я вошел в getenv и обнаружил, что __environ = null с скомпилированными переопределениями. Однако среда содержит правильные значения. __environ имеет правильные переменные после удаления профилировщика.
Кроме того, getenv, кажется, работает с переопределениями pthread в Ubuntu 10.04, с glibc 2.11. К сожалению, обновление не является привлекательным вариантом из-за существующего распространения продукта.
Linux 2.6.31
Глеб 2,5
Мой код инициализации:
inline int init_pthreads_debugger(void)
{
static int recursion=0;
if(!real_pthread_create)
{
// we know that we are single threaded here, because we override pthread_create and
// call this function. Therefore, recursion does not have to be guarded.
if(recursion)
{
return 0;
}
recursion = 1;
init_heap();
void * handle = dlopen("libpthread.so.0",RTLD_NOW);
real_pthread_cond_timedwait =(real_pthread_cond_timedwait_t)dlsym(handle,"pthread_cond_timedwait");
// more pthread initialization functions here.
//do me last to make sure any recursion in dlsym/dlopen is caught
real_pthread_create =(real_pthread_create_t)dlsym(handle,"pthread_create");
recursion = 0;
}
return 1;
}
//an example override
int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t * m, const struct timespec * t)
{
if(!init_pthreads_debugger()) return 0; //no thread, no sync needed.
int ret;
int condition_count;
ptd_note_unblock((void *)m,&condition_count);
ret=real_pthread_cond_timedwait(c,m,t);
ptd_note_block((void *)m,&condition_count);
return ret;
}
спасибо за любую помощь.