C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Есть случаи, когда моя программа неверно!
avb
Отправлено: 03.10.2006, 17:55


Ученик-кочегар

Группа: Участник
Сообщений: 10



Моя программа (довольно сложная и постоянно усложняется — 3D моделирование — BCB 6.0 ) работает много лет во многих торговых точках СНГ (свыше 500 компов)!
И вот за последний год, по крайней мере на двух из них, она выдавала такие штуки — разрешала установку предмета в той ситуации, где эта установка запрещена программно или наоборот, запрещала там, где это ей разрешено! (как будто-бы не срабатывал один из многих операторов 'if'). Тестировал много раз на нескольких десятках компов с Win 2000 и Win XP — запускал до 40 экземпляров своей программы при запущенных Word'e, Excel'e и многих других, что попадались под руку, приложениях, создавал на них те же самые ситуации, но нигде таких ошибок не происходило!
Но на один комп, где произошла ошибка, удалось попасть по горячим следам — видел ошибку сам, закрывал и снова запускал программу — ошибка повторялась. При этом на компе было запущено много чего — 1С, Word с Excel'ем, почтовик, IE и еще что-то. После перезагрузки машины еще долго игрался с программой, но ошибок в тех же ситуация больше не было. На следующий день привез и поставил туда Builder с исходниками, игрался долго — до тех пор пока не увидел, что из нескольких функций отладчик возвращается сразу за их вызовом, но !!! -не в те места в тексте программы, где я в нее отладчиком входил — наверно каким-то образом портился стек — ничего подобного на тех машинах, на которых я когда-либо и много лет работал с Builder'ом, никогда не было!
В общем, понять причину всего этого кошмара мне до сих пор не удалось! Может быть кто-то с подобным сталкивался и может мне что-нибудь посоветовать?
Admin
Отправлено: 03.10.2006, 20:05


Владимир

Группа: Администратор
Сообщений: 1190



Что где-то просто не срабатывает if() — сомневаюсь на 99,9999999%
Тут скорее что-то другое, программное.

А какие внешние библиотеки-компоненты использует программа ?

1. Может Вы подключаетесь к чему либо через OLE Automation.
2. Может используете некий сторонний компонент(ы), (например
для работы с 3D графикой) и этот компонент соответственно
периодически обновляете на более новую версию.
(то есть возможно ошибка не в вашей программе)
3. Создаются неверные условия в if, переполняется некий буфер или
где-то в памяти залезаете на адресное пространство других
переменных/кода.

(то есть ошибка в вашей программе)
Ошибки по памяти — самые неприятные и тяжеловыявляемые.

Пробовуйте вставить в программу ведение log-файла, в который и
попробовать скидывать эти моменты и значения переменных и
условий в некий .txt файл.
Grigoriy
Отправлено: 04.10.2006, 01:39


Мастер участка

Группа: Участник
Сообщений: 381



QUOTE
игрался долго — до тех пор пока не увидел, что из нескольких функций отладчик возвращается сразу за их вызовом, но !!! -не в те места в тексте программы, где я в нее отладчиком входил — наверно каким-то образом портился стек -


Компилируйте свои функции с директивой
__stdcall
и отключите оптимизацию выходного кода в настройках режима компиляции.

Я позавчера вечером и вчера днем тоже никак не мог понять глюка в исполнении своих подпрограмм в одной из моих программ на C++ Builder 6.0. Там особенность такая была... Я код этих подпрограмм написал на встроенном ассемблере. Я иногда так делаю.
Вот так примерно пишется тогда текст
CODE

int __stdcall MyFuncOnAsm(int first_parametr, int second_parametr)
{
int return1;
int a, b, c, d, e;
asm
{
pushad;
//код асма
//и идет этот код можно сказать сколь угодно долго
//одни инструкции процессора
popad;
};
return return1;
};//конец моей функции


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

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

Отредактировано Grigoriy — 04.10.2006, 01:40
avb
Отправлено: 04.10.2006, 11:06


Ученик-кочегар

Группа: Участник
Сообщений: 10



To Admin:
1. OLE Automation не использую
2. Сторонние компоненты, не использую, в графике ошибок тоже нет.
3. Понятно, что "создаются неверные условия в if", но врядли "переполняется некий буфер или где-то в памяти залезаю на адресное пространство других переменных/кода" — программа ни разу не висла, самая большая часть памяти расходуется на хранение и обработку геометрии, но случаев ее неверного графического представления не было. Новые релизы постоянно тестируются с помощью CodeGuard и др.

По поводу log-файла — если б я знал, что это за "эти моменты"!
AVC
Отправлено: 04.10.2006, 11:25


Ветеран

Группа: Модератор
Сообщений: 1583



Описанная ситуация очень сильно напоминает разрушение памяти. Причин может быть множество — выхад за границу, работа с непроиничиализированным указателем ... CodeGuard'ом проверяли?
Особое внимание ассемблерным вставкам. Такие же сбои могут вызываться из-за неправильной работы сторонних библиотек/модулей.

2Grigoriy (для справки)
__stdcall это указание компилятору как передавать параметры функции (в данном случае все в стеке, как принято в C)
в билдере для совместимости с паскалем, на котором написаны компоненты принято использовать __fastcall.
То есть ассемблерная вставка работающая с параметрами обязательно должна учитывать с каким описанием создана функция.
Кроме того очистка стека может быть возложена как на вызываемую функцию, так и на вызывающий код. Про это то же надо помнить.

PS. Пока писал — уже пришел ответ про CodeGuard. Но все равно то же считаю что это на 99% заисывание в "чужую" память.
Admin
Отправлено: 04.10.2006, 11:40


Владимир

Группа: Администратор
Сообщений: 1190



QUOTE
По поводу log-файла — если б я знал, что это за "эти моменты"!


Так log-файл и должен помочь их найти.

Пишите все интересующие переменные, и условия в if перед моментом:

"разрешала установку предмета в той ситуации, где эта установка
запрещена программно или наоборот, запрещала там, где это ей
разрешено"

и если опять будет такой сбой — можно будет полнять этот log
и просмотреть условия и значения переменных перед этим
ошибочным разрешением/запрещением.

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

avb
Отправлено: 04.10.2006, 12:54


Ученик-кочегар

Группа: Участник
Сообщений: 10



To Admin:

Собственно, таким log-файлом и является файл проекта (или заказа), которые программа пишет на диск и еще отправляет, когда это заказ, по почте.
Случаев с ошибкой было всего два из нескольких десятков тысяч — и файлы с этими ошибками у меня есть!
Некоторые подробности:
- при выборе предмета из каталога создается экземпляр объекта, в который, помимо прочего из каталога переписываются свойства предмета (это unsigned __int64, в котором куча свойств устанавливается побитово);
- ошибки при установке предмета возникают при анализе этого свойства;
- файл проекта — это файл собственного формата, где также сохраняется и сцена, а в ней и все ее объекты с координатами установки и этими свойствами. В файле нет геометрии и состава самих предметов и его размер обычно 2 — 5 Кб. Числовые характеристики хранятся в двоичном формате, а текстовые — шифруются по одному из 10 ключей с выбором ключа случайным образом. Т.е. маловероятно, что можно его отредактировать вне программы, можно только испортить и сделать нечитаемым.

В файле с неправильной установкой предмета его свойства не искажены, я открываю этот файл в той же программе и пользуясь командой "Переустановить предмет" пытаюсь установить его неправильно — программа отклоняет эту возможность и сообщает об этом!
Я все-таки склоняюсь к этому 0,1 — 1 проценту! Что это может быть?
Admin
Отправлено: 04.10.2006, 18:21


Владимир

Группа: Администратор
Сообщений: 1190



99,9999999% smile.gif
Ищите ошибку в другом. if не виноват.

Вернуться в Вопросы программирования в C++Builder