Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: crash : _CrtIsValidHeapPointer  (Прочитано 18672 раз)
0 Пользователей и 6 Гостей смотрят эту тему.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« : 26-07-2006 14:04 » 


Господа,

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

В нем происходит какая-то ерунда с объектом класса CString ...
Код:

        BOOL MyClass::CheckInfo()
        {
     CString cstrRes;
     cstrRes=c_strGrund + c_strOption;
             …
     return TRUE;
        }

Константы определены следующим образом в одном из .h-файлов:
Код:

        const CString c_strGrund  (_T("SOFTWARE\\firma\\project\\"));
        const CString c_strOption (_T("OPTIONEN"));

Вызов выглядит так:
Код:

        BOOL StartCompare()
        {
             …
             MyClass myObj;
             myObj. CheckInfo();
        }


Обычно все это работает (сама проверяла). Но при определенном типе приборов при возвращении результата ( return TRUE; ) все летит вверх тормашками... Посмотрела, в чем дело: проблема возникает при вызове деструктора для переменной cstrRes. Если посмотреть на стек, то читаю следующее:
Код:

NTDLL! 7c901230()
NTDLL! 7c96cd80()
NTDLL! 7c960af8()
KERNEL32! 7c85e7af()
_CrtIsValidHeapPointer(const void * 0x09e58e58) line 1697
_free_dbg_lk(void * 0x09e58e58, int 1) line 1044 + 9 bytes
_free_dbg(void * 0x09e58e58, int 1) line 1001 + 13 bytes
operator delete(void * 0x09e58e58) line 351 + 12 bytes
CString::FreeData() line 146 + 15 bytes
CString::~CString() line 213


И как это понимать? .. Причем если бы это было все время, тогда все ОК, а так...
Единственное, что я пока нашла в инете:
http://groups.google.de/group/microsoft.public.vc.language/browse_thread/thread/f2119d45cbf94245/a0c6611969c325c2%23a0c6611969c325c2


но это тоже мне толком ничего не объясняет...

Может, кто-то что-то понимает?
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 26-07-2006 14:13 » 

Иринк, сделай такое движение:

константы
Код:
const char* c_strGrund="SOFTWARE\\firma\\project\\";
const char* c_strOption="OPTIONEN";

и всё ок

Код:
CString cstrRes;
cstrRes=c_strGrund;
cstrRes+=c_strOption;

ну его, этот константный CString , строки лучче Улыбаюсь
« Последнее редактирование: 26-07-2006 14:20 от Алексей1153 » Записан

Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #2 : 26-07-2006 15:34 » 

Леш,

низзя, руки отобьют Ага
У них тут есть свои правила, которых надо придерживаться, так вот одно из них - глобальные строки только как константы...
Да и я этот файл не имею права изменять - его нам поставляет другая группа разработчиков, я сейчас проверила...  Скромно так...

Блин, похоже, что один из модулей, которые вызываются раньше, что-то где-то ломает, но вот кто, где и что?... Найду - убью   Я зол! А не найду - убьют меня, т.к. ошибка имеет высший приоритет важности...  Отлично

Я сейчас получила полное описание ошибки - что и как было сделано для ее появления. Есть надежда, что если с дебагом пройдусь по этой улице, то что-то найду.
Кошмар, я еще ту перерисовку не добила, а тут уже следующий кирпич на мою голову  Отлично
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 26-07-2006 15:49 » 

тогда я могу предложить такое решение: Определить размер данных в константе, создать свою переменную или строку - и скопировать туда. И работать как с родным
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #4 : 27-07-2006 00:50 » new

Смотри, кто тебе строку портит. Это должно происходить как раз в ф-ции, текст которой ты не привела полностью - CheckInfo(). Просто в сложении двух константных строк не может быть ошибки. Кстати, какая студия - 6я? Для неё есть 6ой сервис пак. Стоит?

Ну или если уж на то пошло - попробуй заменить код:
cstrRes=c_strGrund + c_strOption;

на

CString cstrRes = _T("");
cstrRes+=c_strGrund;
cstrRes+=c_strOption;

Хотя это абсурд. Может не эта строка вылетает? Короче, для анализа мало инфы.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #5 : 27-07-2006 07:40 » 

Джон,

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

        CString cstrRes;        
             cstrRes=c_strGrund + c_strOption;
             return TRUE;

так вот вылетает все равно...Это-то меня и поставило в тупик.
Т.е. если кто-то где-то и сделал пакость в хипе, то это было до создания объекта CString, а между этими двумя операторами ничего нет! 

Проблема в том, что я нахожусь в дебаг-версии (не в релиз), кроме того, я иду с дебагом по программе, значит, все располагается в памяти постепенно, без рывков и неожиданных эффектов!!! Я сама не могу найти побольше инфы для анализа...

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

Я попробую еще, как ты сказал, заменить оператор - проверю на всякий случай.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #6 : 27-07-2006 09:21 » 

Malaja, ты уверена что это строки?
может какой-то другой объект ломает твою строчку.
я вчера пол дня долбался(часа два Улыбаюсь ) отлаживая релизную версию(слишком много объектов что бы быстро дебаг собрать рабочий)
ну так вот тоже показывало что эксепшн кидается в строке и в одном и методов класса а оказалось совершенно другое(вовершенно другой объект передавался поссылке разименованием указателя а указатель кривой был)
так что закоментарь всё лишнее и посмотри что получится.
Записан

Странно всё это....
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #7 : 27-07-2006 11:09 » 

LogRus,


вот этого я и боюсь, причем с учетом того, что проект размеров типа "мам ен горюй" (т.е. куча народу уже больше 10 лет туда что-то запихивает), то ничего хорошего это мне не обешает...

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

Проблема в том, что в функции я уже оставила только эти 2 строки, но и это не помогло - все равно на выходе из функции произошел сбой. И это в дебаге!... Я не могу грешить на неточности сборки / установок проекта, т.к. ничего нового в
этой области никто не делал. Вот смотрю сейчас все части по очереди...
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #8 : 27-07-2006 11:40 » 

Malaja,
можно
1. вообще вызов этой функции убрать, на время
2. найти ошибку что называется бинарным поиском Улыбаюсь коментировать большие куски кода и затем потяхоньку убирать коментарии пока не появится ошибка(каждый раз убираешь половину комментариев Улыбаюсь )
3. если ошибка появляется на вызове ретурна можно попробовать обернуть функцию в try catch
bool foo(...)
{

return true;
}
заменить
bool foo(...)
try{
}
catch(...)
{
}

и как нибуть работу студии настроить с исключениями.
4. можно попробовать еще SIG_SEGV натроить(тут люди советуют)
Записан

Странно всё это....
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 27-07-2006 13:14 » 

Продолжаю настаивать на маразматичности происходящего. Для меня единственное логичное объяснение - память повреждается в другом месте. А здесь со строкой только следствие. Я с таким уже сталкивался. Самое абсурдное было - ошибка "исправлялась" добавлением некчёмного действия, например ::OutputDebugString().
Оказалось, что совсем в другом месте для формата был установлен маленький буфер - "впритык", типа: char ch[5]; printf(ch,"COM%d",i);
У всех нормальных людей нет больше 9ти портов (даже в винде зарезервированы константы СОМ1-СОМ9), но неугомонные парни из Зименса умудрились присобачить контроллер на 64 порта. Те в буфер записывалось, например, "СОМ32\0", что было всего! на один байт больше, чем можно. Ошибку искали дня три. Вот это был урок! И хотя прошло уже много лет - "помню как щас". После этого я серьёзно стал относится к подобным вещам.
Я даже где-то на форуме уже рассказывал про нечто подобное. Например, про расположение переменных при объявлении и переполненни буфера. Интересные штуки получаются.
Например, char ch[10]; int i; Тк int - 4 байта, то при переполнении ch (выходе за границы) на один байт будет задействован один байт из i. И никакой ошибки сразу не выскочит.
Эт я к тому, что подобные ошибки искать - легче с нуля проект сделать.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #10 : 27-07-2006 13:30 » 

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

да и без окна студии Malaja сложно говорить о том что есть а чего нет. Улыбаюсь
Записан

Странно всё это....
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #11 : 27-07-2006 15:22 » 

но как найти точку слома не понятно.

"Легче с нуля проект сделать." (с) Ага


Цитата
хотя странно видеть код без проверки на длинну буфера

CString это позволяет. Это враппер для простого массива символов и он хранит эти переменные. Так же в операторах встроены рутины их актуализирования. Он сам обо всём заботится. Поэтому запись CString cstrRes =
c_strGrund + c_strOption; вполне нормальная.

Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 27-07-2006 15:56 » 

Джон, Malaja, а не проще как я предложил ? Улыбаюсь
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #13 : 27-07-2006 22:43 » 

Лёш, а что ты предложил? Проблему это не решает. Однозначно память в другом месте ломается.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #14 : 28-07-2006 05:31 » 

CString это позволяет. Это враппер для простого массива символов и он хранит эти переменные. Так же в операторах встроены рутины их актуализирования. Он сам обо всём заботится. Поэтому запись CString cstrRes =
c_strGrund + c_strOption; вполне нормальная.

Я знаю кто такой CString Улыбаюсь
но предпочитаю std::string, переносимость кода и всё такое.
мне самому нужно подобную багу идти ловить Жаль
Записан

Странно всё это....
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #15 : 28-07-2006 08:15 » 

Мда, таки с нуля писать в этом случае было проще, это точно...
std::string и прочая архитекторы проекта использовать запретили, хотя все разработчики по этому поводу с ними долго ругались. Не помогло...В результате когда надо использовать что-то посложнее обычного CMapа и т.д., приходится изобретать велосипед...
По поводу ошибки - ясно, что память убивают без моего участия. Сейчас выяснилось, что ошибок такого рода нашли штук 5, причем при описании действий тестеров все время возникает один новый модуль. Посему я сейчас возьму его разработчика за то, что ему дорого, и буду с ним смотреть, что он там сделал.

LogRus,
спасибо за SIGSEGV - я сейчас буду искать, как это применяется.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Diletant
Помогающий

de
Offline Offline

« Ответ #16 : 28-07-2006 14:32 » 

В последнее время при работе со сторонними Dll каждый вызов функции из Dll окружаю подобными
Код:

EXCEPTION_RECORD stSavedExceptRec;
CONTEXT stSavedContext;

__try
{
     DllFunc1(pParam);
}
__except(ASSavedExceptRec = *(GetExceptionInformation())->ExceptionRecord,
ASSavedContext = *(GetExceptionInformation())->ContextRecord,
EXCEPTION_EXECUTE_HANDLER)
{
  printf("Dll exception in function %s Addr: %d ExceptionCode: %d", _T("DllFunc1"), stSavedExceptRec.ExceptionAddress,
stSavedExceptRec.ExceptionCode );
  iError = ERROR_FUNC1;
}


конструкциями. При повреждении памяти должно помочь. Содрано у Рихтера (с).

Записан
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #17 : 02-08-2006 08:26 » 

Ребята,

всем еще раз спасибо!
Кажется, я это чудище клыкастое поборола Ага Во всяком случае надеюсь, что поборола, т.к. сейчас эта ошибка пока не выскакивает Ага При анализе кода я наткнулась на одну константу, которая обуславливала количество создаваемых массивов в хипе, которая имела неверное значение (т.е. количество параметров, для которых создавались массивы, увеличили, а константу не изменили). Короче, после этой корректировки пока спровоцировать эту ошибку больше не получается Ага
Посмотрим, что расскажут тестеры по этому поводу.

Diletant,

я попыталась разобраться с твоим примером, но пока безуспешно, а времени конкретно поискать в книжке не было ;-(
Если я у Рихрера не найду соответствующее объяснение, можно будет тебя спросить?
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Diletant
Помогающий

de
Offline Offline

« Ответ #18 : 06-08-2006 10:44 » 

Спросить оно, конечно, можно, но скорый ответ не обещаю. Я появляюсь на форуме сильно нерегулярно. Какой-то непрерывный штурм на работе. Жаль А все достаточно понятно разжевано в пятой части "Создания эффективных Win32 приложений...". На сайте эта книга есть.
Записан
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #19 : 07-08-2006 07:42 » 

Diletant,

о, спасибо за указание главы! В этом случае область поиска сужается и время минимизируется до предельно изумительного! Ага Я же собиралась всю книжку шерстить в поисках нужного Ага
А по поводу аврала на работе - так насколько я могу судить из опыта (Украина+Германия+рассказы родственников и знакомых, проживающих в Штатах и Канаде), это постоянное состояние в этой области ;-( У меня сейчас еще интересней - у меня горят сразу 2 проекта Ага
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines