Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

[C] rhel vs CentOs

40K
11 января 2010 года
himas
31 / / 13.11.2009
Есть приложение, скомпилированное и стабильно работающее под rhel 5.4 (32-BIT насколько помню). Появилась необходимость запустить приложение на сервере с CentOS 5 - 64-BIT.

После копирования исполняемого файла с одной системы в другую, столкнулся с периодически возникающими ошибками работы с памятью (приложение вылетает, ругаясь на free() или malloc()).

Увы, из-за недостатка знаний и опыта, не могу определиться с причиной возникновения проблем:
1. разница в разрядности систем
2. неправильное использование free и malloc/calloc

Прошу помочь разобраться в причине и тем самым наметить пути к решению проблемы.
2
11 января 2010 года
squirL
5.6K / / 13.08.2003
Цитата: himas

Прошу помочь разобраться в причине и тем самым наметить пути к решению проблемы.



причина - перенос бинарника с 32-бит на 64-бита.
пересоберите приложение на новой системе

412
12 января 2010 года
grgdvo
323 / / 04.07.2007
А покажите в CentOS вывод команды
ldd <исполняемый_файл_вашего_приложения>

Это, конечно, может ничего не дать. Но в моей практике работают приложения в режиме совместимости с 32-бит и ничего. Может причина в другом? И что значит "ругаясь на free() и malloc()"? Как ругаясь? Где ругаясь? Что за приложение (хотя бы из какой области)? Пишите больше информации.
2
13 января 2010 года
squirL
5.6K / / 13.08.2003
Цитата: grgdvo
Но в моей практике работают приложения в режиме совместимости с 32-бит и ничего. Может причина в другом? И что значит "ругаясь на free() и malloc()"? .



да работают, конечно. только зачем так извращаться? или у аффтара исходников нету? :)

40K
13 января 2010 года
himas
31 / / 13.11.2009
Цитата: squirL
причина - перенос бинарника с 32-бит на 64-бита.
пересоберите приложение на новой системе



поставил себе на виртуальную машину CentOS 5.4 x86-64
собрал на нем исполняемый файл
закинул на целевой сервер CentOS
поставил права 755
при запуске получаю ошибку:

Цитата:
-bash: /sbin/mysoft: cannot execute binary file



мой CentOS (виртуальная машина):

Цитата:

Linux localhost.localdomain 2.6.18-164.el5 #1 SMP Thu Sep 3 03:28:30 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux



целевой CentOS:

Цитата:

Linux remotehost 2.6.29.5-grsec-hostnoc-4.2.0-i386-libata #1 SMP Wed Jul 8 17:07:07 EDT 2009 i686 i686 i386 GNU/Linux

40K
13 января 2010 года
himas
31 / / 13.11.2009
Цитата: grgdvo
А покажите в CentOS вывод команды
ldd <исполняемый_файл_вашего_приложения>

Это, конечно, может ничего не дать. Но в моей практике работают приложения в режиме совместимости с 32-бит и ничего. Может причина в другом? И что значит "ругаясь на free() и malloc()"? Как ругаясь? Где ругаясь? Что за приложение (хотя бы из какой области)? Пишите больше информации.



Целевой CentOS:

Цитата:

[root@remotehost sbin]# ldd mysoft
linux-gate.so.1 => (0xb7fa2000)
libdl.so.2 => /lib/libdl.so.2 (0x496a6000)
libcrypto.so.6 => /lib/libcrypto.so.6 (0x49b61000)
libssl.so.6 => /lib/libssl.so.6 (0x4a22b000)
librt.so.1 => /lib/librt.so.1 (0x496ee000)
libpthread.so.0 => /lib/libpthread.so.0 (0x496ac000)
libc.so.6 => /lib/libc.so.6 (0x4955f000)
/lib/ld-linux.so.2 (0x4953c000)
libz.so.1 => /usr/lib/libz.so.1 (0x4975b000)
libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0x49e3e000)
libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0x49e6e000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x49d91000)
libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0x49f0d000)
libresolv.so.2 => /lib/libresolv.so.2 (0x49dad000)
libkrb5support.so.0 => /usr/lib/libkrb5support.so.0 (0x4a10e000)
libkeyutils.so.1 => /lib/libkeyutils.so.1 (0x49d96000)
libselinux.so.1 => /lib/libselinux.so.1 (0x49741000)
libsepol.so.1 => /lib/libsepol.so.1 (0x496f9000)



ошибка, с которой вылетает 32-битное приложение на 64-битной системе (просьба скажите если нужен листинг memory map):

Цитата:

*** glibc detected *** mysoft: free(): invalid pointer: 0x4969fff4 ***
======= Backtrace: =========
/lib/libc.so.6[0x495c8595]
/lib/libc.so.6(cfree+0x59)[0x495c89d9]
mysoft[0x804e1eb]
/lib/libpthread.so.0[0x496b15ab]
/lib/libc.so.6(clone+0x5e)[0x49630cfe]
======= Memory map: ========
...

40K
13 января 2010 года
himas
31 / / 13.11.2009
появились некоторые сомнения по поводу достоверности информации от провайдера о разрядности системы. провайдер писал:
Цитата:

Операционная система......: CentOS 5 - 64-BIT


однако:

Цитата:

[root@remoteserver bin]# file ls
ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped



правильно ли я понимаю, что разрядность целевой CentOS 32 бит?

262
13 января 2010 года
Iktomy
1.2K / / 11.10.2004
Цитата: himas
правильно ли я понимаю, что разрядность целевой CentOS 32 бит?



Если я правильно понимаю, вы тут попутали немного. Тут же информация о файле:
ELF - исполняемый файл
32-bit - собран под 32-х битную систему

Но я профан в Юникс, могу ошибаться

40K
14 января 2010 года
himas
31 / / 13.11.2009
Цитата: Iktomy
Если я правильно понимаю, вы тут попутали немного. Тут же информация о файле:
ELF - исполняемый файл
32-bit - собран под 32-х битную систему

Но я профан в Юникс, могу ошибаться



дело в том, что информация о системных файлах в совокупности с информацией о ядре (где написано i386) и невозможностью запустить 64-битный исполняемый файл (ldd mysoft - not a binary file) заставляют задуматься о корректности указанных хостером данных.

Цитата:

Linux remotehost 2.6.29.5-grsec-hostnoc-4.2.0-i386-libata #1 SMP Wed Jul 8 17:07:07 EDT 2009 i686 i686 i386 GNU/Linux

262
14 января 2010 года
Iktomy
1.2K / / 11.10.2004
Ну если сравнить с данными вашей локальной машиной, где в ответе было
 
Код:
Linux localhost.localdomain ... x86_64 x86_64 x86_64 GNU/Linux

и с целевой
 
Код:
Linux remotehost ...i686 i686 i386 GNU/Linux

то тут вы правы, имеет место жестокий обман
412
14 января 2010 года
grgdvo
323 / / 04.07.2007
Цитата: himas
поставил себе на виртуальную машину CentOS 5.4 x86-64
собрал на нем исполняемый файл
закинул на целевой сервер CentOS
поставил права 755
при запуске получаю ошибку:


Все говорит о том, что у хостера 32-битная система (вывод ldd тоже).
Ищите разницу в сборках библиотеки libc.
А вообще squirl в начале был прав :) Если есть исходник (а он судя по всему есть), то проще пересобрать приложение на стороне хостера.

Есть еще такой вариант. Хостер может предоставлять ssh в chroot-режиме (см. man sshd_config, ChrootDirectory). То есть сессия будет работать в некотором специально созданном окружении. С точки зрения безопасности - это правильный подход. Чтобы пользовавтель не делал, он не положит систему. Другое дело, что хостер предлагает в этом окружении. Может действительно система CentOS-64бита, а доступное Вам окружение - это 32-битная урезанная среда. Покапайтесь в файловой системе хостера. Обратите внимание на содержимое /etc /dev /proc /usr/lib/gcc.

40K
14 января 2010 года
himas
31 / / 13.11.2009
Цитата: grgdvo
Все говорит о том, что у хостера 32-битная система (вывод ldd тоже).
Ищите разницу в сборках библиотеки libc.
А вообще squirl в начале был прав :) Если есть исходник (а он судя по всему есть), то проще пересобрать приложение на стороне хостера.

Есть еще такой вариант. Хостер может предоставлять ssh в chroot-режиме (см. man sshd_config, ChrootDirectory). То есть сессия будет работать в некотором специально созданном окружении. С точки зрения безопасности - это правильный подход. Чтобы пользовавтель не делал, он не положит систему. Другое дело, что хостер предлагает в этом окружении. Может действительно система CentOS-64бита, а доступное Вам окружение - это 32-битная урезанная среда. Покапайтесь в файловой системе хостера. Обратите внимание на содержимое /etc /dev /proc /usr/lib/gcc.


I.
мое:

Цитата:

glibc-2.5-42.el5_4.2.i686
libc 2.5


сервер:

Цитата:

glibc-2.5-42.i686
libc 2.5


версии стало быть одинаковые, однако в локальной системе никаких оповещений об ошибках нету (как включить?), даже при запуске с MALLOC_CHECK_=3, когда приложение обязано сообщить об ошибке работы с памятью и завершиться.



II.
насчет режимов - не проверял, но мне кажется что смысла устанавливать на выделенный сервер такие ограничения - нет, но на всякий случай хостеру тикет напишу



III.
попробовал собрать сорцы на целевой системе, все та же ошибка из поста №6.



IV.
приложение имеет один поток, который каждую секунду делает рутинную работу. в нормальном состоянии (в моей системе) приложение постоянно оповещает об очередном старте внутри потока (бесконечный цикл). на сервере же выводится лишь 6-7 сообщений, после чего - тишина. почему так происходит?

412
15 января 2010 года
grgdvo
323 / / 04.07.2007
В этой ситуации даже не знаю, что посоветовать... Видимо на хостера грешить уже не стоит, мне кажется у Вас хитрый баг внутри программы.

Попробуйте следующее:
1. Увеличить verbosity у приложения, поставить дополнительные проверки на большинство системных вызовов, особенно, где malloc, free, а также там, где идет работа с потоками, их синхронизация и работа с общими данными.
ТАКЖЕ СТОИТ! воспользоваться стандартной отладочной методикой. Переопределить вызовы malloc и free на, например, my_malloc и my_free. В этих процедурах записываем в лог-файл все, что передается в качестве параметров (указатель, размер). Потом в лог-файле ищите вызов free для двух одниковых указателей, веротяно кто-то у вас вызывает free на память, которая уже удалена. Частая проблема в многопоточных приложениях.

2. Привлечь gdb :) По своему интерфейсу он неказист (непривычно с командной строкой работать), но когда привыкаешь, то оказывается весьма полезной программой.

Буквально на прошлой неделе занимался тем же самым. Собираем приложение из исходников на glibc2.6.1+gcc4.1.2 все работает, собираем на glibc2.3.3+gcc3.3.3 приложение валится. Перерыли 200 килобайт исходников, ошибка оказалась банальна. Кто-то случайно вместо semname="MySemaphore" написал semname=="MySemaphore". Новый glibc прожевал вызов sem_open с неверно проинициализированным именем, а старый отказывался. Данная строчка была закопана, ну очень глубоко. Убили 3 дня. Кто-то потом проставлялся :)
40K
16 января 2010 года
himas
31 / / 13.11.2009
Всем спасибо, с этой проблемой разобрался.

Проблема зарылась в потоке, который выполнял рутинную работу. Для отправки данных юзал сокеты в совокупности с сетами (fd_set) для таймаутов (в частности для connect). В моем коде было 2 ошибки:

tv.tv_sec и tv.tv_usec я устанавливал до запуска бесконечного цикла while(1), в локальных условиях ошибка не возникала, а на удаленном сервере после первой итерации значения tv.tv_sec и tv.tv_usec приравнивались к нулю и случайному числу соответственно.

Все было бы неплохо, если бы не было второй ошибки, которая заключалась в обработке результата select, где в случаях неудач (а таких вариантов там 4-5) я поставил continue в расчете на то, чтобы приступать к следующей итерации цикла while(1), однако я совсем забыл, что обработка select тоже сидит внутри цикла do .. while() и отсюда поток в бесконечно-быстром режиме (так как sleep там не предусмотрен) бегал по замкнутому кругу.

Это объясняет почему в консоль больше не выводились сообщения + работоспособность программы была подорвана.

Правда для меня до сих пор остается загадкой, почему приложение ругалось на работу с памятью и gdb bt указывал на совсем другие участки кода.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог