Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.NET)
От: Ahriman  
Дата: 21.08.04 17:28
Оценка:
Вчерая столкнулся вот с такой вот проблемой. Есть класс, в котором постоянно происходит чтение-запись реестра. Так вот где-то на пред. «итерации» разработки все было отлично (по другому никак – код тривиальный и уже отлаженный на сто раз). Но после того, как я добавил несколько функций-членов в класс (никак не связанных между собой ни переменными, ни вызовами) – этот метод вдруг перестал работать. Вот как все обстояло: в глоб. (назовём её так) функции создавался дескриптор ключа, а потом другая функция его использовала каждый раз. Так вот – при чтении одного параметра все было ок, а при чтении другого – нет. Win32 API функция RegQueryValueEx возвращала ок, а в в выходном значении (тип параметра) – была какая-то белиберда. Что я только не пробовал – перекомпоновка/перелопачивание не помогло; замена идентификаторов переменных – тоже. Спасло только постоянное открытие-закрытие дескриптора внутри ф-ии. Но ведь это же не избавляет меня от «недопонимания».

Вторая проблема: в моём классе были виртуальные функции, которые обрабатывали события от пользователя. Все было ок, а теперь одна из них вообще не вызывается. И это при том, что код предка класса и код этих функций я вообще никак не мог затронуть!!! Просто смешно.

Расскажу ещё: писал свой связанный список, возникла «плавающая» проблема: иногда указатель вдруг принимал непонятно откуда взявшееся «фантомное» значение! И это при том, что смена его идентификатора ничего также не дала. Какой-то странный баг. Проверил всё: от конструктора копирования до ветвлений

Есть и ещё одно: в дебаге передаю указатель на CDC в польз. Функцию. Все работате. Но как релиз – указателя как не бывало Ж-) Вероятность того, что это всё МОИ косяки – велика, ибо я не считаю себя даже программером «ниже среднего», но ведь 1 проблема явно не моя!

Ну а вот сегодня ещё!!! В той же самой проге, где все косячет (видно косячет все и сразу не просто так!) появилась ещё одна проблема. Функция, которая проверяет привелегии пользователя. Так вот – отдельно (в отдельном простеньком консольном приложении) все работает правильно, а здесь – метод выдает неверный результат!!! Могут ли все эти проблемы возникнуть из-за различных способов компоновки памяти (т.е. у меня много статических методов и переменных, а также виртуальных итд). Статика нужна для простоты работы с потоками, ведь мой класс больше является namespace-хранителем, т.е. создание множества инстанций не предполагается. Но делать все методы статическими как-то мне претит, использую reinterpret_cast.
Re: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.NET)
От: WolfHound  
Дата: 21.08.04 18:32
Оценка: +1
Здравствуйте, Ahriman, Вы писали:

Если бы это был багланд дебилдер то я могбы поверить что это его косяки. Но в то что седьмой вижул так косячит я не верю. Скорее всего все эти проблемы из-за того что ты гдето пишешь за приделы массива, по не вернуму указателю итп. Тем болие что ты сам признаешся что знаешь С++ плохо. Остальные ошибки наведенные.
Воспользуйся BoundsChecker'ом быть может он поможет найти ошибку.
... << RSDN@Home 1.1.4 rev. 142 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: _Winnie Россия C++.freerun
Дата: 21.08.04 19:35
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH> Но в то что седьмой вижул так косячит я не верю.


#include <stdio.h>

int main ()
{
char c[4];
c[0]='a';
c[1]='b';
c[2]='c';
c[3]='d';

printf ( "before: %c%c%c%c\n", c[0], c[1], c[2], c[3] );

for ( int j = 0; j < 2; j++ )
{
for ( int i = 0; i < 3; i++ )
{
c [ i ] = c [ i+1 ];
}

c [3] = 'x';
}

printf ( "after: %c%c%c%c\n", c[0], c[1], c[2], c[3] );

return 0;
}

/*
Roman Pshenichny Bug.
----------------
В debug все правильно, "cdxx". А в release "cxxx".
В VC6 в обоих случаях правильно. IC 7.1 тоже.
У кого какие мнения?
Sorry. 
*/
Правильно работающая программа — просто частный случай Undefined Behavior
Re[3]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: WolfHound  
Дата: 21.08.04 20:16
Оценка:
Здравствуйте, _Winnie, Вы писали:

Ты бы пост перечитал.
... << RSDN@Home 1.1.4 rev. 142 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: _Winnie Россия C++.freerun
Дата: 21.08.04 22:26
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Ты бы пост перечитал.

перечитал
Был еще такой случай "оптимизации": VS7.1 "оптимизировал" функцию случайного числа, так что она в некоторых случаях не выполнялась несколько раз подряд, и выдавала один и тот же результат.
Random random;
int i= random(); //random.operator()
int j= random(); 
int k= random(); 
assert(i == j && k == j);


Симптомы были те же — неправильная работа только в release и только в VC7 .
Помогла замена внутреннего счетчика на volatile (может, этот бубен поможет и автору?).

Еще можно попробовать запустить на других компьютерах / OS, может это несервиспаченный Windows глючит? Попробовать откомпилировать на другом компиляторе (IC++, VC71). Попробовать отключить используемые библиотеки — может в них создаются потоки, которые гадят в память? И свои потоки тоже

А вообще, надо резать проект целиком до минимального кода... Правда, это может занять немало часов.
Правильно работающая программа — просто частный случай Undefined Behavior
Re[5]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: WolfHound  
Дата: 22.08.04 06:58
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>перечитал

О всех этих багах я знаю. Но в данном случае на лицо симптомы порчи памяти.
А автору может помоч только BoundsChecker или ему подобный софт. Хотя лично я даже не знаю как этой штукой пользоваться ибо у меня в этом небыло необходимости даже когда я работал на минном поле ака багланд дебилдер.

И учти

Вероятность того, что это всё МОИ косяки – велика, ибо я не считаю себя даже программером «ниже среднего»,

(С)Ahriman

А еще ошибки седьмого вижула можешь вспомнить? Кроме того что он что-то скомпилить не может? А про ошибки багланд дебилдера я и не только я могу долго расказывать.

Вобщем мое мнение: Вероятность наступить на ошибку кодогенерации в седьмом вижуле практически равна нулю. И учитывая не опытность автора вероятность порчи памяти около 100%.

ЗЫ Искать ошибки в компиляторе (особенно в мелкомягком) последнее дело. А вот проверить свою программу на вшивость...
... << RSDN@Home 1.1.4 rev. 142 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: Ahriman  
Дата: 22.08.04 16:14
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Ahriman, Вы писали:


WH>Если бы это был багланд дебилдер то я могбы поверить что это его косяки. Но в то что седьмой вижул так косячит я не верю. Скорее всего все эти проблемы из-за того что ты гдето пишешь за приделы массива, по не вернуму указателю итп. Тем болие что ты сам признаешся что знаешь С++ плохо. Остальные ошибки наведенные.

WH>Воспользуйся BoundsChecker'ом быть может он поможет найти ошибку.
согласен, что VC не может так косячить, хотя он у меня и без сервис паков... Но я проверял и функциями _Crt*** ...
Re[5]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: Ahriman  
Дата: 22.08.04 16:16
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>Здравствуйте, WolfHound, Вы писали:


WH>>Ты бы пост перечитал.

_W>перечитал
_W>Был еще такой случай "оптимизации": VS7.1 "оптимизировал" функцию случайного числа, так что она в некоторых случаях не выполнялась несколько раз подряд, и выдавала один и тот же результат.
_W>
_W>Random random;
_W>int i= random(); //random.operator()
_W>int j= random(); 
_W>int k= random(); 
_W>assert(i == j && k == j);
_W>


_W>Симптомы были те же — неправильная работа только в release и только в VC7 .

_W>Помогла замена внутреннего счетчика на volatile (может, этот бубен поможет и автору?).
хм.... я уже пробовал... думаю, что у меня скорее всего проблемы с reinterpret_cast, хотя указатель из стат. функции с его исп. получается вроде нормальный
Re[6]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: Ahriman  
Дата: 22.08.04 16:19
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, _Winnie, Вы писали:


_W>>перечитал

WH>О всех этих багах я знаю. Но в данном случае на лицо симптомы порчи памяти.
WH>А автору может помоч только BoundsChecker или ему подобный софт. Хотя лично я даже не знаю как этой штукой пользоваться ибо у меня в этом небыло необходимости даже когда я работал на минном поле ака багланд дебилдер.

WH>И учти

WH>

WH>Вероятность того, что это всё МОИ косяки – велика, ибо я не считаю себя даже программером «ниже среднего»,

WH>(С)Ahriman

WH>А еще ошибки седьмого вижула можешь вспомнить? Кроме того что он что-то скомпилить не может? А про ошибки багланд дебилдера я и не только я могу долго расказывать.


WH>Вобщем мое мнение: Вероятность наступить на ошибку кодогенерации в седьмом вижуле практически равна нулю. И учитывая не опытность автора вероятность порчи памяти около 100%.


WH>ЗЫ Искать ошибки в компиляторе (особенно в мелкомягком) последнее дело. А вот проверить свою программу на вшивость...


но как??? пробовал уже все подряд. Перекомпоновкка/ переименование + проверка на порчу памяти (ф-ии _Crt****). Ед. всех этих тулзов у меня нет. Но ведь студия должна хотя бы ловить утечку памяти и перезапись (типа stack around variable corrupted А этого нет.
Re: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.NET)
От: Павел Кузнецов  
Дата: 22.08.04 18:36
Оценка:
Ahriman:

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


Комментируй код большими кусками. Когда при "отрезании" очередного куска проблема исчезнет, "включи" только что обнаруженный проблемный кусок, и "выключай" по частям теперь его, пока не доберешься до самого проблемного места. Альтернативный способ — проанализировать все фрагменты кода, осуществляющие запись в участки памяти, предшествующие "портящимся" переменным, на предмет записи за границы массивов и т.п.
Posted via RSDN NNTP Server 1.9 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.NET)
От: Nuald Россия http://nuald.blogspot.com
Дата: 23.08.04 07:41
Оценка: 1 (1)
Здравствуйте, Ahriman, Вы писали:

A>Вчерая столкнулся вот с такой вот проблемой. Есть класс, в котором постоянно происходит чтение-запись реестра. Так вот где-то на пред. «итерации» разработки все было отлично (по другому никак – код тривиальный и уже отлаженный на сто раз). Но после того, как я добавил несколько функций-членов в класс (никак не связанных между собой ни переменными, ни вызовами) – этот метод вдруг перестал работать. Вот как все обстояло: в глоб. (назовём её так) функции создавался дескриптор ключа, а потом другая функция его использовала каждый раз. Так вот – при чтении одного параметра все было ок, а при чтении другого – нет. Win32 API функция RegQueryValueEx возвращала ок, а в в выходном значении (тип параметра) – была какая-то белиберда. Что я только не пробовал – перекомпоновка/перелопачивание не помогло; замена идентификаторов переменных – тоже. Спасло только постоянное открытие-закрытие дескриптора внутри ф-ии. Но ведь это же не избавляет меня от «недопонимания».


У меня такого рода проблемы были, когда я не инициализировал структуру, прежде чем ее куда-либо передавать (я передавал ее в WinAPI-функцию, и хотя в MSDN-е было написано, что ее не надо инициализировать, эта функция использовала первый член структуры, указывающий на ее размер). Так что тщательно проверьте, корректно ли вы инициализируете переменные, особенно агрегаты (классы, структуры, массивы).
Про проверку на выход за пределы массива в циклах я не говорю — надеюсь, сами знаете.

A>Ну а вот сегодня ещё!!! В той же самой проге, где все косячет (видно косячет все и сразу не просто так!) появилась ещё одна проблема. Функция, которая проверяет привелегии пользователя. Так вот – отдельно (в отдельном простеньком консольном приложении) все работает правильно, а здесь – метод выдает неверный результат!!! Могут ли все эти проблемы возникнуть из-за различных способов компоновки памяти (т.е. у меня много статических методов и переменных, а также виртуальных итд). Статика нужна для простоты работы с потоками, ведь мой класс больше является namespace-хранителем, т.е. создание множества инстанций не предполагается. Но делать все методы статическими как-то мне претит, использую reinterpret_cast.


Использование reinterpret_cast — признак очень плохого дизайна (не зря это ключевое слово такое неудобное и длинное). Здесь очень высока вероятности ошибки. У себя я использую такое преобразование только в самых экстремальных случаях (например, использование некоторых WinAPI-функций), и то создаю врапперы, которые осуществляют тщательную проверку. Возможно, вам стоит пересмотреть дизайн.
Re[2]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: Ahriman  
Дата: 24.08.04 16:25
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Ahriman:


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


ПК>Комментируй код большими кусками. Когда при "отрезании" очередного куска проблема исчезнет, "включи" только что обнаруженный проблемный кусок, и "выключай" по частям теперь его, пока не доберешься до самого проблемного места. Альтернативный способ — проанализировать все фрагменты кода, осуществляющие запись в участки памяти, предшествующие "портящимся" переменным, на предмет записи за границы массивов и т.п.

Спасибо за совет, но я уже все перепробовал. Я ведь даже если и писал, что не очень круто программлю (иначе не задавалбы таких глупых вопросов), но это-то я умею
Re[2]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: Ahriman  
Дата: 24.08.04 16:27
Оценка:
N>Использование reinterpret_cast — признак очень плохого дизайна (не зря это ключевое слово такое неудобное и длинное). Здесь очень высока вероятности ошибки. У себя я использую такое преобразование только в самых экстремальных случаях (например, использование некоторых WinAPI-функций), и то создаю врапперы, которые осуществляют тщательную проверку. Возможно, вам стоит пересмотреть дизайн.
хм... может и стоит, но косяк видимо даже не из-за этого. Я и без него пробовал, т.е. я менял "архитектуру" именно в этом плане, так как сразу же и стал туда "смотреть". Проблема ещё вот в чем — я наследуюсь от класса, а там куча кода, причем по-идее нормально работающего Придется все переписывать заново
Re[2]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: VladFein США  
Дата: 24.08.04 17:30
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Ahriman:


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


ПК>Комментируй код большими кусками. Когда при "отрезании" очередного куска проблема исчезнет, "включи" только что обнаруженный проблемный кусок, и "выключай" по частям теперь его, пока не доберешься до самого проблемного места. Альтернативный способ — проанализировать все фрагменты кода, осуществляющие запись в участки памяти, предшествующие "портящимся" переменным, на предмет записи за границы массивов и т.п.


Такая техника не поможет если Ahriman испортил память (в результате какой-нибудь ошибки).
Этими "включениями" и "выключениями" Вы просто переместите проявление дефекта из одного места в другое, или временно замаскируете его. Такие упражнения обычно заканчиваются крахом в самый неподходящий момент (прямо перед релизом).
Re: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.NET)
От: Ahriman  
Дата: 24.08.04 18:05
Оценка:
OK, пишу как есть.

Эта вирт. функция, которую вызывает SCM при запуске сервиса!
void CMyContext2::OnServiceStart(){
HANDLE hWatchThread = CreateThread(NULL, 0, CheckForAccess,this, 0, 0);
}

А это та самая статическая функция потока:

DWORD WINAPI CMyContext2::CheckForAccess(LPVOID lpParam){
    while(true){
        BOOL bRetValueToValidate = FALSE;
        //  тут ошибка: возврат дескриптора – НУЛЬ!!!

        HDESK hDesktopDescriptor = 
OpenInputDesktop(0,FALSE, DESKTOP_READOBJECTS);
    
        if (hDesktopOpeningDescriptor){            
                        TCHAR szName[80];
            DWORD cbName;    
            if(GetUserObjectInformation(
                             hDesktopDescriptor, 
                             UOI_NAME, 
                             szName, 
                             80, 
                             &cbName)){
                if(lstrcmpi(szName, _T("default"))!=0)            
                    bRetValueToValidate = FALSE;
            }            
            CloseDesktop(hDesktopDescriptor);    
        }

        if(bRetValueToValidate){
            This->log.Report(MSG_LOGGED);
        }else{
            This->log.Report(MSG_NOT_LOGGED);
        }

        Sleep(3000);
    }
    return 0;
}




так вот… при простом использовании этого кода (т.е. вставляем проверку на наличие пользователя в оболочку) – все работает (так и должно быть), но ЗДЕСЬ!!! Не пашет!!! Вот вам ещё и описание класса (который унаследован от RSDNова CServiceContext ) Так что там никаких глюков не должно быть:

class CMyContext2: public CServiceContext {
public:
    CMyContext2():CServiceContext(){
        log.SetEventSource(SERVICE_NAME,SERVICE_DESC);        
    }
    
    virtual void OnServiceStart();
private:
    CLogger log;
    CSecurity sec;

    static DWORD WINAPI CheckForAccess(LPVOID lpParam);
};


Самое смешное, что до моей переустановки винды (у меня была Икс-ПИ рус без сервис паков  )эта функция работала, а не работала другая  (впрочем и она не пашет).

p.s. Пардон за стремное форматирование — монитор большой
Re[3]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: Nuald Россия http://nuald.blogspot.com
Дата: 25.08.04 04:57
Оценка:
Здравствуйте, Ahriman, Вы писали:

A>хм... может и стоит, но косяк видимо даже не из-за этого. Я и без него пробовал, т.е. я менял "архитектуру" именно в этом плане, так как сразу же и стал туда "смотреть". Проблема ещё вот в чем — я наследуюсь от класса, а там куча кода, причем по-идее нормально работающего Придется все переписывать заново


Тогда возьми на вооружение принципы рефакторинга — это тебе поможет (если уж нет другого выхода, как все переписывать).
Re: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.NET)
От: Аноним  
Дата: 25.08.04 06:12
Оценка:
Здравствуйте, Ahriman

Если я правильно понял то ты пытаешся передавать адреса виртуальных функций(приведя их через reinterpret_cast) в API функции типа CreateThread(или аналоги типа beginthreadex), если так, то это верный способ создать глюкодром.
Re[3]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: ZeusSon  
Дата: 25.08.04 12:08
Оценка: -1
Здравствуйте, _Winnie, Вы писали:

_W>Здравствуйте, WolfHound, Вы писали:


WH>> Но в то что седьмой вижул так косячит я не верю.


_W>[ccode]

_W>#include <stdio.h>

_W>int main ()

_W>{
_W>char c[4];
_W>c[0]='a';
_W>c[1]='b';
_W>c[2]='c';
_W>c[3]='d';

_W>printf ( "before: %c%c%c%c\n", c[0], c[1], c[2], c[3] );


_W>for ( int j = 0; j < 2; j++ )

_W>{
_W>for ( int i = 0; i < 3; i++ )
_W>{
_W>c [ i ] = c [ i+1 ];
_W>}
_W>c [3] = 'x';
_W>}
....
ГОСПОДА! Фишка действительно в памяти и ее защите в релизе... Попробуйте к сему коду поставить char c[5]; И все зафурычить как должно. Просто релиз смущает инструкция автора
c [ i ] = c [ i+1 ];
которая при значении i=3 не понимает "как человек взявший меня(VS7) такое пишет". Хотя действительно вроде операция безобидна.
Re[2]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: Ahriman  
Дата: 25.08.04 17:13
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Ahriman


А>Если я правильно понял то ты пытаешся передавать адреса виртуальных функций(приведя их через reinterpret_cast) в API функции типа CreateThread(или аналоги типа beginthreadex), если так, то это верный способ создать глюкодром.


ок, как мне быть без глюкодрома? Использовать везде статические члены? Не катит ... А как проверить, что этот реинтерпрет каст не работает? Кстати — и без него все точно так же выполняется, но видимо ...
Re[7]: Были ли у Вас такие проблемы (баги?) - MSVC++ 7.0 (.N
От: Wawan Россия http://www.wawan.ru/resume
Дата: 27.07.06 04:49
Оценка:
A>но как??? пробовал уже все подряд. Перекомпоновкка/ переименование + проверка на порчу памяти (ф-ии _Crt****). Ед. всех этих тулзов у меня нет. Но ведь студия должна хотя бы ловить утечку памяти и перезапись (типа stack around variable corrupted А этого нет.

студия не должна ловить утечку и перезапись памяти и не ловит, я видел только когда студия ругается на заюзывание непроиниченной переменной.
для поиска всех остальных багов есть софт специальный
Numega Bound Checker например
найди его поставь, вещь в быту программиста нужная, могу поспорить что он найдёт милион багов в твоей проге
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.