The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"free() рушит приложение при том что с памятью всё ок..."
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"free() рушит приложение при том что с памятью всё ок..."
Сообщение от Serega_S emailИскать по авторуВ закладки(ok) on 04-Июл-04, 15:49  (MSK)
   Привет всем! Случилось страшное!!! Может быть конечно виноват я сам, но! В ниже приведённом коде free() вызывает Сегментэйшн фаулт. Проследил указатель - в норме, тобишь не изменяется (со времени выделения) и всё вроде пучком. Может быть это из-за того, что я делаю многопоточное приложение и нужно использовать специальные библиотеки... Но я уже -lpthread подключал - то же самое. Мож я что ещё забыл? Подмогните!
Вот код:
       tmp=(char*)malloc(m.len_data-m.adreses*sizeof(int)+1);
if(!tmp)
{
set_log("next_connect",errno);
return(void*)-1;
}
+
*(pam+m.len_data-1+sizeof(int)*m.adreses)=0;
sprintf(tmp,"%s:%s",adres,pam+m.adreses*sizeof(int));
//update(tmp);
free(tmp);

Вот пример отладки:

Breakpoint 1, next_connect (uk=0x8057100) at functions.cpp:381
381       tmp=(char*)malloc(m.len_data-m.adreses*sizeof(int)+1);
(gdb) watch tmp
Hardware watchpoint 2: tmp
(gdb) p tmp
$1 = 0x0
(gdb) n
Hardware watchpoint 2: tmp

Old value = 0x0
New value = 0x80860c8 "8??@?\211\a\bm\001"
next_connect (uk=0x8057100) at functions.cpp:382
382 if(!tmp)
(gdb)
388 *(pam+m.len_data-1+sizeof(int)*m
.adreses)=0;
(gdb)
389 sprintf(tmp,"%s:%s",adres,pam+m.adreses*sizeof(int));
(gdb)
391 free(tmp);
(gdb) p tmp
$2 = 0x80860c8 "10.0.0.1:Client connect!"
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x409b7c90 in chunk_free (ar_ptr=0x40a6b620, p=0x80860c0) at malloc.c:3231
3231 malloc.c: No such file or directory.
in malloc.c
Current language:  auto; currently c

P.S.: Единственная мысть возникает - переход на системные функции выделения памяти (из-за подобных косяков под виндой пришлось так же поступить в своё время), но уж больно много кода лопатить. И за Линукс обидно - не винда ведь!!! ДОЛЖЕН работать - ведь на то он Линукс!

  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "free() рушит приложение при том что с памятью всё ок..."
Сообщение от ACCA Искать по авторуВ закладки(ok) on 04-Июл-04, 19:27  (MSK)
В таких случаях пробуй читать вслух в лицах:


> if(!tmp)
> {
>  set_log("next_connect",errno);
>  return(void*)-1;
> }
[...]
> free(tmp);

[...]
>next_connect (uk=0x8057100) at functions.cpp:382

Раз ты получил надпись "next_connect", значит у тебя tmp=0.


>391   free(tmp);

Ты сделал free на нулевой указатель.


>Program received signal SIGSEGV, Segmentation fault.

И получил segmentation fault (что определяется по тому, что 0 по адресу 0 больше не 0).

  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "free() рушит приложение при том что с памятью всё ок..."
Сообщение от XMan Искать по авторуВ закладки(??) on 04-Июл-04, 19:37  (MSK)
Я не являюсь знатоком gdb, но что-то мне подсказывает, что число 382 в строках:

next_connect (uk=0x8057100) at functions.cpp:382

и

382 if(!tmp)

обозначают одно и то же понятие - номер строки в исходнике. То есть, в этой строке расположен "if(!tmp)", что не является критичным.
Да и "next_connect" появляется не после "free", а перед "if".

Что я упустил из виду ?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "free() рушит приложение при том что с памятью всё ок..."
Сообщение от Serega_S emailИскать по авторуВ закладки(ok) on 05-Июл-04, 05:19  (MSK)
>обозначают одно и то же понятие - номер строки в исходнике. То
>есть, в этой строке расположен "if(!tmp)", что не является критичным.
>Да и "next_connect" появляется не после "free", а перед "if".
>
>Что я упустил из виду ?

То что next_connect (uk=0x8057100) at functions.cpp:382 - это уведомление, что в этой строчке бряк и он сработал.
    Что-то все запутались с next_connect - это функция так называется. Если бы срабатывал if, то это было бы видно в листинге работы дебаггера (если его можно так назвать - листинг).

Вот так вот.

                                 С уважением, Сергей.


  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "free() рушит приложение при том что с памятью всё ок..."
Сообщение от Serega_S Искать по авторуВ закладки(ok) on 05-Июл-04, 03:09  (MSK)
>next_connect (uk=0x8057100) at functions.cpp:382

>Раз ты получил надпись "next_connect", значит у тебя tmp=0.
next_connect - это так функция называется тоже, и на ней я поставил бряк

перед тем как выполнить free  я в дебаггере p tmp сделал - посмотрите получше - там всё видно.
>>391   free(tmp);
>
>Ты сделал free на нулевой указатель.

Я именно сделал упор+привёл листинг дебага что tmp НЕ МЕНЯЕТСЯ и он НЕ НУЛЕВОЙ.

>И получил segmentation fault (что определяется по тому, что 0 по адресу
>0 больше не 0).

Вот так. Читайте лучше вопрос - в хорошем вопросе содержится половина ответа. :-)))

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "free() рушит приложение при том что с памятью всё ок..."
Сообщение от XMan Искать по авторуВ закладки(??) on 04-Июл-04, 19:30  (MSK)
Он и работает. И с потоками тоже. А если ты выдаляешь 10 байт и пишешь туда 11, то никакая ОС не спасет твоей программы, хотя нормальная ОС сама выживет :)
Числа приведены в качестве примера, ибо понять, колько ты выделяешь и сколько пишешь не предстваляется возможным.

Кроме того, не факт, что именно в этой переменной проблемы. Например, ты можешь устроить переполнение буфера где-то в начале программы, а зависнет внутренняя функция из библиотеки, например, постгреса, вызванная в одном из потоков через час работы этой самой программы.

---

Для проверки двойного free можешь перед компиляцией задать переменную окружения "MALLOC_CHECK_=1" и посмотреть, что программа будет орать на stderr. За подробностями "man malloc".

  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "free() рушит приложение при том что с памятью всё ок..."
Сообщение от Serega_S emailИскать по авторуВ закладки(ok) on 05-Июл-04, 05:37  (MSK)
>Он и работает. И с потоками тоже. А если ты выдаляешь 10
>байт и пишешь туда 11, то никакая ОС не спасет твоей
>программы, хотя нормальная ОС сама выживет :)
>Числа приведены в качестве примера, ибо понять, колько ты выделяешь и сколько
>пишешь не предстваляется возможным.

Дык это лопатить весь код? А по-другому как-нибудь нельзя? Уж больно много лопатить... Может что-нибудь наподобии "MALLOC_CHECK_=1" есть?

>Кроме того, не факт, что именно в этой переменной проблемы. Например, ты
>можешь устроить переполнение буфера где-то в начале программы, а зависнет внутренняя
>функция из библиотеки, например, постгреса, вызванная в одном из потоков через
>час работы этой самой программы.

Кстати тоже там баг ещё один был - ни с того ни с сего падал QString string=... Причём тоже все параметры в порядке. И это происходило до описанной выше баги. Наверно это из той же оперы. Може есть какая-нибудь прога для отслеживания работы с памятью?

>Для проверки двойного free можешь перед компиляцией задать переменную окружения "MALLOC_CHECK_=1" и
Насчёт двойного фрии - по идее (хотя это в винде так было) - при очищении памяти, она обычно сразу забивается мусором. тобишь это было бы видно в дебаггере. И тем более это маленький кусочек кода - память только выделилась и тут же очистилась - это если только как-то в другом потоке очищается, но уж больно хитро. Хотя я естественно проверю.

>посмотреть, что программа будет орать на stderr. За подробностями "man malloc".
>
А точно не нужно подключать особенные библиотеки для многопоточного приложения? Под виндой нужно было.


  Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "free() рушит приложение при том что с памятью всё ок..."
Сообщение от XMan Искать по авторуВ закладки(??) on 05-Июл-04, 15:25  (MSK)
> при очищении памяти, она обычно сразу забивается мусором. тобишь это было бы видно в дебаггере.

Обычно память ничем не забивается, а остается такой, какой она была на момент free. Прочто система отмечает у себя, что этот кусок памяти свободен и его можно будет кому-нибудь отдать по запросу.

Касательно автоматизации поиска ничего не могу сказать. Это как раз самая неприятная ошибка. Потому подавляющее большинство эксплоитов построены именно на переполнении буфера.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "free() рушит приложение при том что с памятью всё ок..."
Сообщение от XMan Искать по авторуВ закладки(??) on 05-Июл-04, 15:29  (MSK)
Или вот еще из той же оперы:

void func(void** param) {
  param* = malloc(.....);
  free(param*);
}
...

А теперь запускаем два потока, каждый из которых вызывает эту функцию и передает указатель на одну и ту же переменную.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "free() рушит приложение при том что с памятью всё ок..."
Сообщение от qq Искать по авторуВ закладки on 05-Июл-04, 12:48  (MSK)
а вот интересно, ты самый простой вариант проверял?
сделай

printf("size of tmp: %d\n",m.len_data-m.adreses*sizeof(int)+1);

и перед самым free сделай

printf("strlen tmp: %d\n",strlen(tmp));

и сравни...

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру