Задача ослеживания утечек памяти.

Тема в разделе "LANGS.C", создана пользователем neutronion, 3 мар 2011.

  1. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    neutronion
    а как адресуются страницы? что это вообще такое?
    а для такого стека

    call VirtualAlloc
    mov [Esp_store], esp
    lea esp, [eax + this_block_len]

    ?

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

    для вирусов это не критично, тк срок жизни виря/троя редко превышает 3 месяца. а о глючности требований к нему почти не стоит.
     
  2. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    я даже не знаю зачем вы мне доказываете свой способ с метками.
    ну, используйте если так хотите. я свое мнение сказал, а как поступите вы: через метки, образ, тиб или еще как - дело ваше.

    вот еще маленький пример распространенной ошибки

    char* a = my_malloc(8);
    char* b = my_malloc(10); // допустим, они выделятся подряд

    sprint(a, "123456789"); // видно, что строка превышает размер буфера a и затирает метку в начале буфера b.
    // в хип менеджерах основанных на метках это частая причина нарушений в работе хипа и утчек памяти
     
  3. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    Ну так замечательно! Таким образом схема с метками как в вышеприведенном способе, будет решать еще одну задачу! После того как
    мы, что либо пишем в буфер, мы теперь можем проверить не произошло ли переполнение буфера проверив метку, как в этом случае. Значит теперь метка служит уже 2 целям:
    1 - контроль переполнения буферов
    2 - контроль утечек. Не здорово ли?

    вот вариант с меткой
    Код (Text):
    1. char* a = (char *)malloc(8+4);
    2. memset(a+8,'a',4);
    3. char* b = (char *)malloc(10);  // допустим, они выделятся подряд
    4.  
    5. sprintf(a, "123456789");
    6.  
    7. if(memcmp(a+8,"aaaa",4))
    8. {
    9.     /// ПЕРЕПОЛНЕНИЕ БУФЕРА БОЛЬШАЯ ОШИБКА!!!
    10.     return 0;
    11. }
    Два джина в одном флаконе!
     
  4. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    даже подряд идущие маллоки не гарантируют, что эти области будут идти подряд или что между них не будет других областей или разрывов в выделенной памяти. даже то не гарантируется, что более поздний маллок выделится по более старшим адресам.

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

    ----
    я не знаю для чего вы так доказываете свою мысль. писать/отлаживать/сдавать вашу прогу не мне.
    если вы делаете по этому вопросу рос, то доказывание мне - это не рос.
    я не ваш заказчик, веса мое мнение для вашего заказчика не имеет. не вижу причин для подобных доказательств.
     
  5. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    Причем здесь, когда и где вызывается маллок? На вышеописанный код это никак не повлияет. Как проводилась проверка целостности на переполнение и проверку на удаление из хипа, так и будет, из за разной последовательности вызовов маллока и нахождения указателей на данные, проверки как работали так и будут работать корректно .
    Код при тестировании обязательно должен проходить необходимые многочисленные проверки в дебажной версии.
    В релизе это можно убрать.
     
  6. seeerg

    seeerg New Member

    Публикаций:
    0
    Регистрация:
    25 янв 2011
    Сообщения:
    5
    Борьба с утечками памяти - это борьба с кривостью рук (с).
     
  7. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    neutronion
    в дебаг версии замените маллок на выделение буффера на границе страницы, а следующую делайте невалидной, и все будут счастливы)
     
  8. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    Как это сделать?
     
  9. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
  10. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    Да не! Great что-то другое имел ввиду.
     
  11. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    AsmGuru62
    у меня она сделала следующее - подключенная к ней прога обычно жрущая около метра-2х озу и выполняющейся около 30 сек захватила около 2 гиг озу и через 40 минут стартования на полной загрузке проца свалилась с истошным мессаж бохом.
     
  12. fsd

    fsd New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    353
    например так
    Код (Text):
    1. void*
    2. __cdecl
    3. malloc_overruntest(
    4.     IN  size_t  Size
    5.     )
    6. {
    7.     VOID*   pData   = NULL;
    8.  
    9.     if((pData = VirtualAlloc(NULL, ALIGN_UP(Size, PAGE_SIZE) + PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS)))
    10.     {
    11.         if((pData = VirtualAlloc(pData, ALIGN_UP(Size, PAGE_SIZE), MEM_COMMIT, PAGE_READWRITE)))
    12.         {
    13.             pData = (VOID*)((ULONG_PTR)pData + (ULONG_PTR)(ALIGN_UP(Size, PAGE_SIZE) - Size));
    14.         }
    15.     }
    16.  
    17.     return pData;
    18. }
    19.  
    20. void
    21. __cdecl
    22. free_overruntest(
    23.     IN OUT  void*   pData
    24.     )
    25. {
    26.     VirtualFree((VOID* )ALIGN_DOWN(pData, PAGE_SIZE), 0, MEM_RELEASE);
    27. }
    28.  
    29. #ifdef _DEBUG
    30. #    undef  malloc
    31. #    define malloc malloc_overruntest
    32. #    undef  free
    33. #    define free free_overruntest
    34. #endif
    35.  
    36. ULONG
    37. AppEntry()
    38. {
    39.     CHAR*   pTest   = malloc(9999);
    40.  
    41.     pTest[9998] = '\0';// OK
    42.     pTest[9999] = '\0';// Access violation writing location
    43.  
    44.     free(pTest);
    45.  
    46.     ExitProcess(ERROR_SUCCESS);
    47. }
    точно так же можно проверить и на ошибки buffer underrun, но неясно зачем это все если есть спец ПО типа Application Verifier и Driver Verifier которое проверяет это
     
  13. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    Для блочного тестирования. Application Verifier предпологает, что приложение уже создано. Мне же надо просто тестировать части приложения в дебаггере. Вот этот код замечательно пока себя оправдывает ввиду своей простоты.
    Код (Text):
    1. _CrtMemState s1, s2, s3;
    2.  
    3. void StartLeakDetection()
    4. {
    5.          //s1, s2, s3; надо бы здесь их обнулить
    6.     _CrtMemCheckpoint( &s1 );
    7. }
    8.  
    9. bool StopLeakDetection()
    10. {
    11.     _CrtMemCheckpoint( &s2 );
    12.     if ( _CrtMemDifference( &s3, &s1, &s2) )
    13.     {
    14.         //leak!!!!!
    15.         return false;
    16.     }
    17.     return true;
    18. }
    19.  
    20.  
    21. void Main()
    22. {
    23.     StartLeakDetection();
    24.  
    25.     //здесь делаем выделения и освобождения
    26.    
    27.     if(true != StopLeakDetection())
    28.     {
    29.         //утечка!!!!
    30.     }
    31.  
    32.  
    33. }
     
  14. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    У такого решения есть минус. Они жирное, если требуется выделения памяти до 1000 байт.
     
  15. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
     
  16. fsd

    fsd New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    353
  17. fsd

    fsd New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    353
    это используется только для верификации, к чему ваш коментарий не ясно
    или вы и в продакшен версии использовать решили?
     
  18. neutronion

    neutronion New Member

    Публикаций:
    0
    Регистрация:
    31 мар 2010
    Сообщения:
    1.100
    Просто ваше решение неплохое, но опять таки, оно не подходит, если память выделяется кусочками от 2 до 255 байт. Хотя, для других целей, неплохое решение. Буду иметь ввиду. У Рихтера есть подробное описание этого, что-то я упустил. Спасибо за пример.
     
  19. fsd

    fsd New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    353
    страница не committed и исключение будет соответственно другое так что не нужно ее гардовой называть, фактически только ее описатель создается
    это не мое
    еще раз - чем не подходит?
     
  20. qqwe

    qqwe New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2009
    Сообщения:
    2.914
    neutronion
    вы хотите сделать идеальный контролер работы с памятью? почему б тогда не оттолкнуться от какой нибудь открытой либы - виртуализатора х86/х64? будете иметь контроль над каждым обращением к памяти.