[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

отладка под gdb



Привет.

Столкнулся со странным поведенем программы, запускаемой из отладчика (под gdb). Начал выяснять. Обнаружилось, что если в программе есть несколько нитей, то при "хождении по шагам" нити могут просыпаться, хотя они сидят на вызове sem_wait(&sema), а сам "sema" - ещё имеет нулевой счетчик.

Удивился. Погуглил. Оказывается, с этой проблемой сталкиваются многие, и происходить это может не только под отладчиком (например, запускаем программу, Ctrl-Z, затем fg. Всё, если были нити, которые сидят на семафорах, то они начтут выполняться).

Обход это проблемы тоже был более-менее одинаков - вместо sema_wait() делаем что-то типа "while(sema_wait()==-1);". Документация, оказывается, не соответствует действительности.

Сделал. Проблема ушла. Частично. Теперь уход в background/вывод в foreground происходит корректно. Но. Под отладчиком теперь получаем такое:
Program received signal SIGSEGV, Segmentation fault.

Напоследок проверил отладку под insight - версия в sarge просто отказалась отлаживать эту программу.

Всё. Приплыли. Как вообще можно отлаживать программы - непонятно.

Компилируем так "gcc -o test_thread test_thread.c -g -lpthread "
Вот сам код (test_thread.c), ничего лишнего, примитивней некуда:
#include <unistd.h>
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>

sem_t global_S;

void* test_thread(void* ptr)
{
	int ret=0;
	
	sleep(1);
	printf("1\n");
	sleep(1);
	printf("2\n");
	sleep(1);
	printf("3\n");

	
	ret=sem_post(&global_S);
	if (ret)
		printf("FAIL in thread: 0x%08X\n", ret);

	return 0;
}

int main()
{
	int ret=0;
	pthread_t thread_id;
	
	/* создаём семафор */
	ret=sem_init (&global_S, 0, 0);
	if (ret) goto fail;

	/* создаём и запускаем нить */
	if (pthread_create(&thread_id, NULL,
		test_thread, NULL)!=0)
	{
		ret=-2;
		goto fail;
	}


	/* ждём семафора */
	{
		int rc=0;
		{
			rc=sem_wait(&global_S);
		} while(rc==-1);
	}

	/* освобождаем выделенные ресурсы */
	ret=sem_destroy(&global_S);
	if (ret) goto fail;

	printf("all ok\n");
	return 0;

fail:
	printf("FAIL: ret=0x%08X\n", ret);
	return 1;
}



Версии программ (gcc, gdb, insight)- из Sarge. Ядро 2.6.15 из backports

--
  С уважением, Василий.



Reply to: