LINUX.ORG.RU

Сообщения slesh

 

segfault в backtrace

В общем случилась беда. В программе отслеживаю падение и делаю backtrace, но в некоторых случаях происходит второй segfault внутри вызова backtrace. Как так получается?

Вызываю tracesize = backtrace(trace, 128);

 

slesh
()

Странное дробление данных передаваемых через сокет

В общем проблема вот в чем: Есть клиент (Windows). Он подключается к серверу (Linux), отсылает ему 17 байт ЗА ОДИН SEND!!! У сервера стоит TCP_DEFER_ACCEPT на сокет (30 сек). т.е. логика такая, что accept сработает как только придет первый пакет данных от клиента или пока не истечет время 30 сек. И так вот - работает всё отлично. Если клиент за 30 сек не отправил данные, то значит это не правильный клиент.
Ну так вот, проблема в том, что сервер после accept делает:

Len = recv(Sock, &Pack, sizeof(PACKET), MSG_NOSIGNAL | MSG_DONTWAIT);
И получается так что приходит не полный пакет. т.е. Len = 14 байт, а не 17 байт. Как такое может быть?
У меня логика такая:

  1. После коннекта клиента буфер отправки на клиенте пуст и по этому 17 байт вместит точно.
  2. Так как все 17 байт отправляются за один send то значит 100% они попадут в буфер и не разобьются.
  3. Размер 17 байт по любому меньше размера окна TCP и размера буфера отправки, по этому по идее уйдут они в одном TCP пакете
  4. Сервер за счет TCP_DEFER_ACCEPT ждет появления данных.
  5. Как только пришли данные, то они считываются без блокирования сокета. Так как мы сразу знаем сколько данных придет и что они будут в одном tcp пакете то они всегда должны быть целиком получены, но увы на деле не так.

В 10% случаях данные считываются именно 14 байт, а не 17. Может дело в какой-то настройке в Linux ? Причем глюки начинаются когда идет нагрузка на сервер.

 ,

slesh
()

Глюки с fwrite

Словил пару раз глюк: Есть файл, открытый как f = fopen(FileName, «a+b»); В файл пишутся данные fwrite(&data.val, sizeof(data.val), 1, f); val имеет тип u_int64_t При этом периодически в файле начинают встречаться записи не по 8 байт, а по 9 байт. и во всех случаях в этих записях встречается \r\n

Т.е. как я понял при fwrite если во входных данных встречается \n, то в файл записывается \r\n

Запись производится только из одного потока. Чтение не используется. Периодически используется fflush(f);

Система: Linux Debian-60-squeeze-64-minimal 2.6.32-5-amd64 #1 SMP Tue Jun 14 09:42:28 UTC 2011 x86_64 GNU/Linux

Такое ощущение что иногда игнорируется тот факт что файл открыт в двоичном режиме. При этом специально спровоцировать глюк не удаётся в тестовой программе.

slesh
()

iptraf не видит eth0

Столкнулся с такой вот проблемой: на некоторых серваках iptraf видит только lo. т.е. если зайти в Detailed interface statistics то там он предлогает смотреть статистику только для lo. Хотя на других серверах предлагает и eth0.

Сервера где не видит eth0: Linux Debian-60-squeeze-64-minimal 2.6.32-5-amd64 ifconfig - показывает норм информацию (lo и eth0) Может кто нибудь сталкивался с такой вот проблемой?

P.S. при этом в General interface statistics показывает и lo и eth0 P.P.S обнаружил странность. если запускать сразу с параметрами: iptraf -d eth0 то всё отлично показывает

slesh
()

Code::Blocks глючит подсказка кода

Может кто-нибудь сталкивался с такой вот проблемой: Для всех файлов отлично работает подсказка кода. И прототипы функций нормально показываются и имена функции тоже, и константы, и так для всех файлов проекта + то, что через include добавлено. Но для файла arpa/nameser.h вообще отказывается показывать хоть что-то. Ни структуры, ни константы, ни имена функций не видит. Уже и добавлял папку /usr/include/arpa для поиска, всё равно не пашет. Причем только на этом файле.

Пролистал файл - вроде в нем всё нормально, ничего специфического, а работать не хочет.

При этом если написать функцию и сделать find declaration of: то опять же нормально работает, кроме функций из arpa/nameser.h

slesh
()

неблокируемые connect

небольшой вопрос появился: Когда я делаю connect для неблокирующего сокета, то по идее должно вернуться -1 и в errno записаться EINPROGRESS. Но во многих источниках указано, что такое поведение будет только в случае, если соединение не может быть установлено сразу. Т.е. подразумевается то, что могут быть случаи, что даже при такое раскладе connect сразу установит соединение и вернет 0. Вот главный и вопрос: реально ли такое поведение или нет? Или же connect для неблокирующего сокета никогда не сможет сразу установить соединение?

slesh
()

Как указать DNS сервер для res_query?

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

Пытался сделать так:

	u_char  answer[512];
	int     n;

	res_init();

	_res.nsaddr_list[0].sin_addr.s_addr = inet_addr("8.8.8.8");
	_res.nsaddr_list[0].sin_family = AF_INET;
	_res.nsaddr_list[0].sin_port = htons(53);
	_res.nscount = 1;

	n = res_query("test.com", C_IN, T_A, answer, sizeof(answer));

	printf("%i\n", n);

т.е. чтобы запрос шел не на DNS сервера прописанные подефолту в системе, а не DNS сервер гугля. Но почему-то запрос всё равно отправляется на сервера указанные в системе.

P.S. Linux 2.6.32-32-generic (Ubuntu 10.04)

slesh
()

Создание скриптов содержащих файлы

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

Хотелось бы знать существует ли специальная программа для этого или это всё ручками собирается?

slesh
()

двойной pthread_mutex_lock

Столкнулся с задачкой. В программе есть главный поток и определенное кол-во других потоков. Главный поток инициализирует всю работу, затем делает pthread_mutex_lock(&work_mutex). Далее делает повторно pthread_mutex_lock(&work_mutex) чтобы ожидать разблокировку. Если какому-либо потоку понадобится чтобы программа корректна завершилась, то он сделает pthread_mutex_unlock(&work_mutex), тем самым разблокирует работу главного потока, который корректно всё завершит. Переменная work_mutex - глобальная.

В доках написано, что такое нельзя делать т.к. по мнению системы происходит взаимная блокировка (функция вернет EDEADLK). Но так как на деле ни в одном из используемых дистрибутивов Linux данная ошибка не появлялась, то было решено использовать вышеописанный код. Но пришлось портировать программу на FreeBSD, а вот там как раз и словил данную ошибку (EDEADLK).

Как можно вообще всё это более менее корректно реализовать?

slesh
()

Как узнать имя функции по её адресу (из отладочных символов)

Ситуация такая: Через sigaction ставится обработчик на SIGFPE, SIGILL, SIGSEGV, SIGBUS с флагом SA_SIGINFO. В обработчике происходит добавления записи в лог. В лог попадает информация об ошибке:

  1. Время ошибки
  2. Из siginfo_t - значение si_addr
  3. Из контекста - значение регистра EIP/RIP

Т.е. допустим если произошла ошибка SIGSEGV, то si_addr указывает на адрес памяти к которому было обращение, а EIP/RIP на адрес команды которая выполнила это действие.

И вот главный вопрос: Как по EIP/RIP узнать имя функции, которой принадлежит данный адрес? Если программа компилируется с отладочными символами, то вычислить имя функции вроде как возможно, а вот как это сделать - хз. Может быть есть какая-нибудь функция для этого?

slesh
()

Изменить имя потока

Возможно ли в Linux как-то задавать имена для потоков запускаемых через pthread_create, чтобы в списке процессов(ps/htop) потом можно было видеть различные имена для различных потоков.? А то неудобно когда все потоки имеют такое же имя как и исполняемый файл + параметры запуска

slesh
()

Размер очереди UDP пакетов

Подскажите люди добрые, где можно в Debian настроить очередь для UDP пакетов. Ну и желательно посмотреть её размер. А то постоянно сталкиваюсь с такой проблемой - при приходе большого числа UDP пакетов, часть из них отбрасывается т.к. не хватает места в очереди

slesh
()

многопоточный recvfrom

Есть сокет (в блокирующем режиме) ожидающий коннект на определенный порт, и есть проц 4-х ядерный. Что если запустить на каждое ядро по 1 потоку и в этих потоке делать recvfrom для этого сокета. И вот главный вопрос: Будет ли в этом случае прирост производительности? И вообще можно ли такое делать? Как я понимаю если пришло сообщение то допустим в первом потоке обрабатываются данные полученные через recvfrom, в это время если пришли данные, то другой поток будет обрабатывать их. Так?

slesh
()

Вопросы по поводу MSG_OOB

Интересует вот такие вот вотпросы.
1) через TCP соединены Linux программа и Windows программа.
Если я в Linux программе делаю send с флагом MSG_OOB, то сможет ли Windows приложение получить данные если делает recv без флага MSG_OOB ?
Если да, то будет ли толк от этого? Данных буквально 12 байт шлется. Или обязательно необходимо чтобы и recv был с флагом MSG_OOB ?

2) в чем может быть ошибка при следующей сетуации:
- Серверное приложение под линукс открывает 2 порта.
- Клиенты - windows приложения. коннектятся на первый порт
- При некоторых условиях клиенту шлется сообщение чтобы он подключился на второй порт.
- При учачном или неудачнмо коннекте клиентом отсылаются данные о результате подключения.

И вот заметил такую вешь: Когда одновременно допустим 150 клиентам дать команду коннекта на второй порт то сыпятся такие вот ошибки:
1) клиент не получает сообщения. хотя на серверноей стороне send вернул что всё норм. Встречается редко.
2) А вот более частая сетуация: у клиента connect на второй порт вылетает по таймауту. Хотя на серверной стороне нет никаких промедлений. т.е. после accept сокет сразу добавляется в epoll. в listen задана очередь 1000.
При этом добавления судя по логу идут мгновенно.

Наиболее ответ интересует по поводу второй ошибки. Такое ощущение что чтото с конфигом TCP.

slesh
()

Странности с pthread

Разъясните пожалуйста один момент. Есть код:

void* MA_ClientRouteProc(void* param)
{
    -.-.-.-.-.-.-.-.-.-.-.-
    return 0;
}

if (!pthread_create(&th, 0, MA_ClientRouteProc, param))
{
    -.-.-.-.-.
}
И вот при такой конструкции при каждом запуске потока теряется вирт. память. т.е. htop показывает что на 8 метров становится меньше вирт. памяти. При этом поток завершается удачно. strace показал:
[pid 21925] mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_32BIT, -1, 0) = 0x43040000
[pid 21925] mprotect(0x43040000, 4096, PROT_NONE) = 0
[pid 21925] clone(Process 21926 attached child_stack=0x43840250, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x438409e0, tls=0x43840950, child_tidptr=0x438409e0) = 21926
-.-.-.-.-.-.-.-.-.-.
[pid 21926] _exit(0)                    = ?
Process 21926 detached
т.е. как видно как раз и было выделено 8 метров памяти через mmap под стек. Но после завершения потока почему-то эта память не освободилась, и нигде не было munmap.
В чем может быть ошибка? или это такое специфическое поведение системы.

slesh
()

Завершение потомков при завершении родителя

Столкнулся с такой проблему:
1) Есть bash скрипт запущенный в фоне.
2) Этот скрипт при старте проверяет запущен он или нет. И если нет, то создает pid файл.
3) Далее скрипт запускае определенный процесс и следит за его работоспособность. т.е. если процесс завершился с определеннымм кодами, то скрипт перезапускает этот процесс. При других кодах ошибки скрипт тоже завершает свою работу
4) при завершении работы скрипта, он удаляет PID файл

И вот теперь главный вопрос: необходимо сделать так, чтобы при прибитии процесса скрипта (допустим через kill с использованием pid файа), чтобы автоматом завершался и дочерний процесс.
Если просто убить процесс скрипта, то дочерний всё равно продолжает работать.
Или как вариант надо сделать так, чтобы дочерний процесс получал уведомление о том, что родител завершил свою работу и автоматически сам закрылся.

slesh
()

Закрытие сокета при неотправленных данных

Столкнулся с такой проблемой: большое кол-во данных отсылаю в сокет, потом shutdown(sock, SHUT_RDWR); и close(sock); но на приемной стороне приходит только часть данных. Потому что после close они уже теряются на сервере.
Пробовал играться с SO_LINGER - не помогает. теже глюки остаются. Утанавливаемое время не играет роли тоже. Пробовал уже и shutdown убирать. Ничего не помогает.

Сокеты все неблокирующие и крутятся в epoll.
После отсылки делать пауза перед закрытие нет возможности, чтобы у других клиентов не было ожидания большого.
Кто что может подсказать по этому поводу?
P.S. система дебиан x64

slesh
()

Книги по программированию в Linux

Собственно говоря, может быть кто-нибудь знает какие-нибудь книги по программированию в Linux, желательно по новее, то почти все книги 2000-2004 года и почти везде наибольший уклон сделан в частности на ядро 2.4 Вообще желательны книги по сетевому и системному программированию. Пока что нашел только (может кто нибудь посоветует что-то лучшее (кроме man )):
1) Шон Уолтон - Создание сетевых приложений в среде Linux. 2001 год сам за себя говорит
2) Роберт Лав - Linux. Системное программирование. 2008 год - понравилась. Но смахивает на структурированный перевод man
3) KEIR DAVIS, JOHN W. TURNER - The Definitive Guide to Linux Network Programming. 2008 года. В принципе норм, но некоторых моментов нет
4) Майкл К. Джонсон, Эрик В.Троан -Разработка приложений в среде Linux Второе издание. 2007 год - норм.

Также хотелось бы чтобы было в них хоть чуть инфы по фряхе.

slesh
()

Cоответствие WinApi и Linux Syscalls

Перерыл весь инет, нигде не смог найти такую таблицу соответствия. т.е. интересует какие функции в линуксе могут быть аналогами WinApi функциями. Необязательно чтобы это были системные вызовы, пойдут и библиотечные функции. Максимум что находил - исходники и хидеры реализующие обертку над системными вызовами.
т.е. требуется что-то типа такого:
CreateFile - open/creat
MapViewOfFile - mmap
итд итп.

slesh
()

Блокировка удаления открытого файла

Столкнулся с одной такой вот проблемой: когда я открываю /создаю файл через open(FileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); То почему-то я могу его удалять через консольные команды типа rm А вот как сделать так, чтобы файл нельзя было удалить до тех пор пока я его не закрою? Вообще файл используется для последующего отображения в память через mmap и постепенного изменения некоторых данных в нем. При этом если файл удалить, то маппинг нормально работает и не выдает ошибок. В конце работы даже munmap и close без ошибок выполняются и при этом данные которые изменялись уже никуда не записываются

slesh
()

RSS подписка на новые темы