LINUX.ORG.RU

Сегфолт программы xneur

 ,


0

2

У меня xneur с git падает при блокировке экрана xlock.

xneur[6499]: segfault at 7a7163 ip b7ec0320 sp bfe26420 error 4 in libxneur.so.21.0.0[b7eb4000+1f000]

Я пересобрал программу с debug и через gdb определил место в котором падает.

Program received signal SIGSEGV, Segmentation fault.
0xb7ecbf68 in keymap_init (handle=<optimized out>, display=<optimized out>)
    at keymap.c:660

660			if (strcmp(p->handle->languages[i].dir, "us") == 0)

Вот код из программы:

for (int i = 0; i < p->handle->total_languages; i++)
	{
		// FIXME Replace hardcode "us" to setting
		if (strcmp(p->handle->languages[i].dir, "us") == 0)
		{
			p->latin_group = i;
		}
}

И вроде как вполне нормальный код, как на него может влиять мой блокировщик экрана? Если закоментировать этот код, то сегфолта нет.

★★★★★

break в условии вставить, что бы при выполнении условия цикл прерывался, + заменить strcmp на strncmp, ну а так просто printf("%i",i); и глядеть в какой интерации ловим прикол, может быть total_languages считается с 1 тоесть по количеству и поэтому его размер на 1 больше чем чем languages[i], вот и выходим за пределы

Deleted ()
Последнее исправление: Deleted (всего исправлений: 2)

if (strcmp(p->handle->languages.dir, «us») == 0)

Тут может быть или выход за пределы массива languages или неправильный указатель dir. Для теста можешь вынести p->handle->languages.dir в отдельную переменную.

В любом случае: надо смотреть код выше по стеку вызовов чтобы понять как вообще такое могло произойти.

Deleted ()
Ответ на: комментарий от Deleted

В p->handle->languages.dir у нас массив полученный хрен пойми откуда

И как strncmp с этим поможет?

есть там нультерминал или нет не ясно

Вот это и надо выяснить путём чтения кода. Если есть, то оставить strcmp. Если нет, то менять на strncmp.

Если просто неглядя заменить на strncmp, то получится обычный кривой говнокод. Хотя бы потому, что не понятно что ей указывать в качестве длины.

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)

Я бы так обвешал и выяснил чё к чему сразу


printf("[DEBUG] Total=%i \n", p->handle->total_languages);
for (int i = 0; i < p->handle->total_languages/*-1*/; i++)
{
    printf("[DEBUG] Count=%i Compare=%s \n",i,p->handle->languages[i].dir);
    if (strcmp(p->handle->languages[i].dir, "us") == 0)
    {   printf("[DEBUG] Found='us' in %i count \n",i);
        p->latin_group = i;
        //break;//exit if found
    };
}

Deleted ()
Ответ на: комментарий от Deleted

да, проблема в этой штуке.

сделал код вида:

for (int i = 0; i < p->handle->total_languages; i++)
	{
	log_message (ERROR,"my number %i", i);
	log_message (ERROR,"my language %s", p->handle->languages[i].dir);
		// FIXME Replace hardcode "us" to setting
		if (strcmp(p->handle->languages[i].dir, "us") == 0)
		{
			p->latin_group = i;
			break;
		}
	}

В логе получаю:

[ERR] 10:31:56 my number 0
[ERR] 10:31:56 my language us
[ERR] 10:32:15 my number 0
Ошибка сегментирования
предпоследняя строка это как раз xlock запускаю, и дальше language не определился уже.

irton ★★★★★ ()
Ответ на: комментарий от irton

Смотри откуда и при каких условиях эта функция второй раз вызывается.

И, ещё раз, вынеси куда-нибудь p->handle->languages.dir. Чтобы понять, проблема в указателе p->handle->languages или в указателе p->handle->languages.dir.

Deleted ()
Ответ на: комментарий от Deleted

Спасибо буду пробовать, пока только выяснил что:

[ERR] 10:49:07 total 2
[ERR] 10:49:07 my number 0
[ERR] 10:49:07 my language us
[ERR] 10:49:07 my number 1
[ERR] 10:49:07 my language ru

[ERR] 10:49:12 total 19649496
[ERR] 10:49:12 my number 0
Ошибка сегментирования

но если в коде поставить break то оно же не должно дальше совпадения пройти....

irton ★★★★★ ()
Ответ на: комментарий от irton

[ERR] 10:49:12 total 19649496

Вот это намекает, что где-то ранее или забыли это поле инициализировать, или его повредил посторонний код в том же процессе, или указатель на всю структуру, содержащую поле, указывает не туда.

Deleted ()
Ответ на: комментарий от Deleted

с целью познания, захардкодил вместо p->handle->total_languages цифру 2

ничем не помогло конечно. Но нашел что languages.dir задается на основе total_languages т.е. вроде как связь есть

handle->languages[handle->total_languages].dir	= strdup(short_name);
		tmp = realloc (handle->languages[handle->total_languages].dir, sizeof(char) * 3); // 'xx' + '\0'
		if (tmp == NULL)
			continue;
		handle->languages[handle->total_languages].dir	= (char *)tmp;
handle->languages[handle->total_languages].dir[2] = NULLSYM;
irton ★★★★★ ()
Ответ на: комментарий от Deleted

Нуллтерминал есть в «us», так что на 3м байте сравнение завершится наверняка. Любое отличие от «us» тоже завершит сравнение.

mittorn ★★★★★ ()
Последнее исправление: mittorn (всего исправлений: 1)

Почитал тред, понял что ты в отладчик типа не умеешь. Вот алгоритм действий:

Выполняешь такой вот код в произвольной директории куда у тебя есть доступ на запись:

# задаём положение и имя дампа памяти глобально на всю систему до перезагрузки
sudo sysctl kernel.core_pattern=core-%e-%s-%u-%g-%p-%t

# включаем неограниченные по размеру дампы памяти процесса в текущем экземпляре оболочки
ulimit -c unlimited

# запускаем целевую программу
<programm name>

# ... воспроизводим падение ...

# запускаем отладчик над дампом памяти 
gdb $(which <programm name>) -c *core-* 

# проверяем состояния переменных печатая их:
print p
print *p
print p->handle
# и так далее...
onhydro ()
Ответ на: комментарий от onhydro

все закончилось на этапе sysctl kernel.core_pattern=core-%e-%s-%u-%g-%p-%t не найден этот путь. получилось снять только:

(gdb) info stack
#0  0xb7ed52a6 in keymap_init (handle=0xe95620, display=0xf421a0)
    at keymap.c:661
#1  0xb7edc52e in window_init_keymap (p=0xeed190) at window.c:148
#2  0xb7ed8ad1 in program_process_input (p=0xeed920) at program.c:421
#3  0x004522e3 in main ()
(gdb)

Разработчик уже вроде на этот форум давно не заходит, видимо придется просто закоментировать код.

irton ★★★★★ ()
Ответ на: комментарий от onhydro
 #sysctl kernel.core_pattern=core-%e-%s-%u-%g-%p-%t
sysctl: cannot stat /proc/sys/kernel/core_pattern: Нет такого файла или каталога

у меня ядро самосборное и debug весь отключен.

irton ★★★★★ ()
Последнее исправление: irton (всего исправлений: 1)

Я собрал xneur из гита и попробовал запустить под valgrind. Итог:

==21380== ERROR SUMMARY: 22739 errors from 276 contexts (suppressed: 2 from 1)
Не удивительно, что оно падает.

Deleted ()
Ответ на: комментарий от irton

Ну, роняй тогда под отладчиком или приаттачившись. Чуть больше телодвижений. Алгоритм поиска ошибки тот же - сначала находишь какой именно кусок памяти испорчен/не проинициализирован. Если испорчен - ищещь кто портит с помощью watch. Если не проинициализирован - инициализируешь.

onhydro ()
Ответ на: комментарий от onhydro

Да ну несогласен. Нормальная система для пользования а не разработки и отладки.

Ну, роняй тогда под отладчиком или приаттачившись. Чуть больше телодвижений. Алгоритм поиска ошибки тот же - сначала находишь какой именно кусок памяти испорчен/не проинициализирован.

Так и делаю. Но print p и print keymap_init ничего нового не показывают, а дальше я смутно представляю что делать.

irton ★★★★★ ()
Ответ на: комментарий от onhydro

Сегфолт программы xneur (комментарий)

Если судить по значению total, то мусор получается, total это у меня выводится p->handle->total_languages и я пока не понимаю этой записи, указатель на указатель на total_languages какой-то? Handle передается как аргумент в функцию, может с ним что не так становится и он начинает указывать в «молоко»

На total_languages завязан и languages.dir если я правильно понял код. Но чего ради значение с 2 меняется на мусор - я не могу пока сказать.

irton ★★★★★ ()
Последнее исправление: irton (всего исправлений: 2)
Ответ на: комментарий от irton

Да, даже если и нет - можно такие вещи искать с помощью rr(rr.org).

Запиши дамп с помощью rr, посмотри адрес total. Поставь memwatch на этот адрес. Мотай назад пока не увидишь, какой код записывает в total это мего значение.

onhydro ()
Ответ на: комментарий от onhydro

Мотай назад пока не увидишь, какой код записывает в total это мего значение.

Судя по тому, что показывал valgrind (куча использований неинициализированных значений), может быть никто туда ничего и не записывает =).

Deleted ()
Ответ на: комментарий от Deleted

Ну как, после запуска программы я же вижу значение 2, а при запуске xlock это значение меняется на большое число. А должно остаться 2 (2 это количество раскладок в системе, может быть и 1 и 3)

irton ★★★★★ ()
Ответ на: комментарий от Deleted

Вот именно что указатель сбивается (я так по дилетантски прикидываю) а значение раскладок не меняется. Либо количество раскладок подсчитывается второй раз и неправильно уже.

И то и то одновременно думаю не очень вероятно.

irton ★★★★★ ()
Последнее исправление: irton (всего исправлений: 1)