Допустим, сделана опечатка и неправильно написано какое-нибудь ключевое слово. В этом случае при попытке запуска программы внизу появляется окно, в котором отображены сообщения об ошибках. При этом программа не запустится. Благодаря подсказке такую ошибку легко найти и исправить.
Частой ошибкой начинающих является пропуск конструкции begin – end в цикле. При
этом имеется в виду, что в цикле должны выполняться, например, обе команды, но на самом-то деле в цикле, конечно, будет выполняться только первая, а вторая выполнится только один раз – потом, когда программа выйдет из цикла. При попытке запуска появляется сообщение. Но это не ошибка, а предупреждение. В нем обращается внимание на то, что параметр цикла после выполнения цикла может быть неопределенным (он присутствует во второй команде).
Однако, несмотря на предупреждение, программа может запуститься. Если вводятся
дкакие-либо данные, то появляется сообщение об исключительной ситуации – exception. При этом программа приостанавливается, переходя из режима исполнения в режим отладки. Чтобы перейти к обычному редактированию кода, лучше остановить программу. Это можно сделать с помощью команды Program Reset. Затем можно поправить ошибку и вновь запустить программу.
В большие программы всегда закрадываются ошибки. Их надо быстро и квалифицированно найти и исправить.
Механизм исключительных ситуаций (exception)
одно из больших достоинств Delphi. С их помощью вы можете контролировать
возникновение ошибок и создавать в результате устойчивые к ошибкам программы.
По мере знакомства с языком и средой программист проходит несколько этапов. На
первом этапе он, по незнанию, путает типы, забывает ставить знаки препинания (например, точку с запятой в конце строки), некорректно использует операторы и т.п. В результате написанный им код в принципе невозможно исполнить. И это хорошо – 15 поскольку допущенные им ошибки оказываются автоматически выявленными на этапе компиляции, более того, часто среда программирования сама подсказывает, какая ошибка допущена, и, что важно, указывает строку, которую нужно поправить. По мере изучения языка и борьбы с синтаксическими ошибками программист плавно переходит к следующему этапу. Теперь он уже не делает таких простейших ошибок, но, поскольку сложность его программ возрастает, возрастает и вероятность совершения им ошибки, при которой программа все равно запустится. Поскольку, с точки зрения компилятора, явной ошибки нет, а некоторые странности кода, по-видимому, являются замыслом программиста. Однако компилятор все-таки сообщает об этих странностях с помощью предупреждений (Warning).
Советуем всегда обращать на них внимание, проверять при их появлении, нет ли ошибки, и вообще стараться писать код так, чтобы не было предупреждений.
Опасность таких скрытых ошибок состоит:
1) в том, что они таятся в той части кода, которую программист написал и уверен, что
она правильная (программа запустилась), а значит, и не очень внимательно будет
искать ошибку;
2) в том, что проявляется эта ошибка совсем в другом месте кода – не в том, в котором
допущена. А это приводит к долгим поискам ее по всей программе.
При возникновении исключительной ситуации можно проигнорировать ее и запустить
исполнение программы дальше, нажав F9. В этом случае программа выдает сообщение об ошибке. Необходимо найти ошибку – понять, в какой строке и почему происходит сбой. Для этого можно воспользоваться трассировкой. Для того чтобы определить первую строчку, начиная с которой будет проводиться трассировка, нужно поставить Breakpoint – точку останова.
Когда исполняемый код доходит до точки останова, исполнение программы
приостанавливается, и надо перейти в режим отладки. В режиме отладки можно исполнять последовательно программу по шагам, контролировать и изменять значения переменных и т.п. Этот режим служит для обнаружения и ликвидации ошибок. В этом случае появляется возможность просмотреть или изменить текущие значения переменных, однако изменение кода во время отладки невозможно. Измененный текст заработает только после перезапуска программы.
Чтобы выполнить текущую строку, на которой стоит курсор отладки, нажмите F7 или
F8. Строка выполнилась, и курсор сместился. Если необходимо перейти к следующей строке, то можно нажать F8, если нужно зайти в какую-либо функцию, то нажимают клавишу F7 и продолжают трассировку.
Для того чтобы в ходе отладки узнать значение той или иной переменной, нужно просто подвести к ней курсор. Появится hint со значением этой переменной. Это, однако, работает не со всеми переменными, а только с доступными в данный момент. Если нужно постоянно контролировать значение переменной, то еще проще добавить ее в список Watch.
Для более основательного слежения за значениями можете воспользоваться Списком Наблюдения (Watch List, Ctrl+F5).
Таким образом, при программировании среда Delphi может находиться в различных
режимах:
• Режим редактирования – режим, в котором редактируется код проекта,
модифицируется форма, добавляя на нее компоненты и настраивая их свойства. Это
основной режим.
• Режим исполнения программы – режим, в который среда переходит, как только
нажата клавиша F9 и был построен exe-файл. Фактически, в этом режиме происходиткак раз исполнение получившегося exe-файла проекта. Программа исполняется так,
как если бы ее вызвали не из Delphi, а просто из Windows.
• Режим отладки – в этот режим можно перейти из режима исполнения программы.
При этом программа будет приостановлена (но не остановлена совсем).
Чтобы продолжить трассировку (последовательный переход от команды к команде),
можете воспользоваться клавишами:
• F9 (Run) – продолжить программу, не трассируя ее.
• F8 (Step over) – выполняется текущая строка кода, и переходят к следующей строке.
• F7 (Trace Into) – то же, что и F8, с тем отличием, что если в текущей строчке
содержится вызов какой-либо функции или процедуры, то попадают внутрь этой
процедуры и трассируют ее до конца, затем из нее возвращаетс и переходят к
следующей строке (на которую перешли бы сразу, если бы нажали F8).
• F4 (Run to Cursor) – переход в режим исполнения программы до тех пор, пока не
должна будет выполнена строка, на которой стоит текстовый курсор (аналогично
тому, как если бы была установлена точка останова)
• Shift+F8 (Run Until Return) – процедура выполняется до конца.
• Ctrl+F2 (Program Reset) – остановка трассировки и переход в режим редактирования
кода. (Иногда целесообразнее, если это не грозит ошибками, продолжить исполнение
программы (F9) и выйти из нее нормальным образом, закрыв главную форму).
При работе в Delphi сообщение об ошибке фактически появляется дважды: сначала
выводится окно об исключительной ситуации и программа приостанавливается, а потом,
если нажать F9 (F8, F7 и т.п.), – возникает стандартное сообщение об ошибке Windows.
Итак:
1. Произошла ошибка.
2. Программа приостанавливается.
3. Выводится сообщение об exception. Это сообщение для программиста. Среда Delphi
сообщает, что программа не в состоянии выполнить какую-то свою команду.
Программист не предусмотрел возможность исключительной ситуации. Среда Delphi
приостанавливает программу, чтобы программист разобрался, где и в чем ошибка.
Отключить приостановку (2)–(3) можно, сняв флажок Menu => Tools => Debugger
Options => Language Exceptions => Stop on Delphi Exceptions.
4. Нажатие клавиши F9 (F8, F7 или др.).
5. Выводится сообщение об ошибке. Это сообщение для пользователя программы
(ситуация запуска приложения не из Delphi, а через exe-файл из Windows, т.е. не
существовует пунктов 2, 3, 4).
6. Программа продолжается (при этом она не сумела выполнить ту часть, в которой
произошла ошибка, и значит, если эта часть важная, продолжение может
сопровождаться дальнейшими ошибками).
Механизм обработки исключительных ситуаций заключается в том, что если
произошла ошибка (1) и не надо выводить (5), предпринимаются действия, чтобы (6) исполнялось корректно.
Для этого «опасная» команда (или целый блок) помещается внутрь конструкции try..except..end или try..finally..end.
Блок try..finally..end используется аналогично try..except.., но с тем отличием, что блок
команд между finally и end выполняется в любом случае, вне зависимости от того, было исключение между try и finally или нет.
Как узнать код ошибки try except
- Подписаться на тему
- Сообщить другу
- Скачать/распечатать тему
|
|
Senior Member Рейтинг (т): 3 |
Подскажите, можно ли как нибудь отловить код ошибки? //readln(A); =0; try Z:=Z/A; except on E: exception do ShowMessage(e.messages); end; Ну это конечно ясно, что он напишет ‘Division by zero’, но это во-первых по английски, а во вторых, если мы напишем сразу сообщение по русски, т.е. так: //readln(A); =0; try Z:=Z/A; except ShowMessage(‘Деление на ноль!’); end;
и допустим, что ошибка произошла не из-за того, что делится на ноль, а из-за чего-нибудь другова — то естественно сообщение будет ложным, а точнее неверным. //readln(A); =0; try Z:=Z/A; except on E: exception do if (e.messages=’Division by zero’) then ShowMessage(‘Деление на ноль’) else ShowMessage(e.messages); end;
Почему вариант тупой, да потому что, перед тем как вставить текст сообщения об ошибке надо: Хочется что-то типа того, что текст ошибки сообщения мог бы заменять какой-нибудь её индетификатор, чтобы можно было типа такого: //readln(A); =0; try Z:=Z/A; except on E: exception do if (e.код_ошибки=123) then ShowMessage(‘Деление на ноль’) else ShowMessage(e.messages); end; где «123» есть индетификатор ошибки, т.е. заменяет сам текст ‘Division by zero’. Да, и у e нет параметра на английском, что я написал на русском код_ошибки. Ууууу…. Пока писал — сам устал. |
CodeMonkey |
|
on E: EDivByZero do Подробно и в деталях. |
Continental |
|
Senior Member Рейтинг (т): 3 |
Спасибо за ссылку. except on E: EIBInterBaseError do begin sShowMessage(e.ClassName,e.Message); exit; end; а он мне пишет: Неизвестная переменная EIBInterBaseError Вообще класс такой есть, он даже его показывает, если я делаю так: try Connected:=true; except on E: exception do sShowMessage(e.ClassName,e.Message); end; Вот e.ClassName как раз и есть EIBInterBaseError, только я не могу класс коде указать. Сообщение отредактировано: Continental — 27.10.09, 14:48 |
mitrich |
|
Senior Member Рейтинг (т): 99 |
Хелп говорит, что EIBInterBaseError находится в юните IB |
CodeMonkey |
|
Цитата Continental @ 27.10.09, 14:21 А вот в каком модуле находятся классы исключений при работе с ibx компонентами.
Пуск/Поиск. *.pas с текстом EIBInterBaseError. Цитата Continental @ 27.10.09, 14:21 Вообще класс такой есть, он даже его показывает, если я делаю так Вместо except on E: SomeClass do … можно (но не рекомендуется) использовать: except on E: Exception do if E.ClassName = ‘SomeClass’ then … else raise; |
Continental |
|
Senior Member Рейтинг (т): 3 |
ММММ…. всё равно прочитав всё, не могу реализовать то что я хочу. Так вот я хочу сказать, что в двух случаях ошибки совсем разные, а вот класс исключения один и тот же. try IBDataBase.Connected:=true; except on E : что здесь должно быть, чтобы определить 1-й случай? do begin sShowMessage(‘несуществующий путь бд!’); exit; end; on E : что здесь должно быть, чтобы определить 2-й случай? do begin sShowMessage(‘неверный пользователь или пароль’); exit; end; on E : Exception do begin //люая другая ошибка sShowMessage(e.ClassName,E.Message+’ совершенно другая ошибка’); exit; end; end; Помогите разобраться пожалуйста, я очень хочу сделать так, но не знаю. |
CodeMonkey |
|
Цитата Continental @ 27.10.09, 15:51 Так вот я хочу сказать, что в двух случаях ошибки совсем разные, а вот класс исключения один и тот же. Если у вашего EIBDataBaseError нет какого-нибудь IBErrorCode — то это криво спроектированные классы Interbase. Цитата Continental @ 27.10.09, 15:51 Так я не могу понять, как же мне отловить первую ошибку, или вторую вот с помощью такой конструкции: Если никакого поля с кодом нет, то по-хорошему — никак. (Т.е. вы можете, конечно, попробовать анализировать сообщение, но ведь его могут локализовать). Добавлено 27.10.09, 16:13 try IBDataBase.Connected:=true; except on E: EIBDataBaseError do if E.ErrorCode = XXX then begin sShowMessage(‘несуществующий путь бд!’); exit; end else if E.ErrorCode = YYY then begin sShowMessage(‘неверный пользователь или пароль’); exit; end else raise; end; Добавлено 27.10.09, 16:15 try IBDataBase.Connected:=true; except on E: Exception do begin if E is EIBDataBaseError then begin if EIBDataBaseError(E).ErrorCode = XXX then begin sShowMessage(‘несуществующий путь бд!’); exit; end else if EIBDataBaseError(E).ErrorCode = YYY then begin sShowMessage(‘неверный пользователь или пароль’); exit; end; end; ShowMessage(e.ClassName,E.Message+’ совершенно другая ошибка’); end; end; Добавлено 27.10.09, 16:17 |
mitrich |
|
Senior Member Рейтинг (т): 99 |
Цитата CodeMonkey @ 27.10.09, 16:11 Если у вашего EIBDataBaseError нет какого-нибудь IBErrorCode
Именно так это свойство и называется, что нетрудно узнать из хелпа (который надеется на длительное и плодотворное сотрудничество с Continental |
Continental |
|
Senior Member Рейтинг (т): 3 |
С облегчением … try Connected:=true; except on E : EIBInterBaseError do begin sShowMessage(IntToStr(e.IBErrorCode),E.Message); exit; end; Спасибо всем, что открыли глаза. Добавлено 27.10.09, 17:01 except on E: Exception do begin if E is EIBDataBaseError then begin if EIBDataBaseError(E).ErrorCode = XXX then Я теперь это заделал в applicationevents. Теперь у меня будет и лог вестись и сообщения об ошибках выводится! Е-Е-Е! |
CodeMonkey |
|
Для лога ошибок имеет смысл использовать хук на исключения. См. JCL, EurekaLog, madExcept. Помимо сообщения этот способ позволит получить стек вызовов и состояние процессора в момент ошибки. С этой информацией зачастую продиагностировать ошибку можно даже не запуская отладчик. |
0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
0 пользователей:
- Предыдущая тема
- Delphi: Общие вопросы
- Следующая тема
[ Script execution time: 0,0393 ] [ 16 queries used ] [ Generated: 12.06.23, 20:16 GMT ]
В некоторых случаях при возникновении ошибок, во время отладки, компилятор показывает строчку дельфовых библиотек, где именно возникло исключение. Например обращение к несуществующему индексу массивов и прочих контейнеров, как здесь:
List1 := TList.Create;
List1.Add(P);
P := List1.Items[1];
Получим указание на строку: Error(@SListIndexError, Index);
в System.Classes
В больших многопоточных проектах отловить подобные ошибки через трассировку бывает крайне сложно, записывать лог после каждой строки — тоже не вариант. А хотелось бы знать строку своего проекта от куда это все началось. Как нибудь можно выявить искомую строку в режиме отладки?
Zam
1873 серебряных знака12 бронзовых знаков
задан 28 мар 2017 в 21:02
7
Для этого нужно:
- Текущее состояние стека. В нем хранится последовательность вызовов функций/процедур (Call Stack), которая привела нас в место возникновения исключения, а также значения всех локальных переменных и входных параметров всех этих функций/процедур.
- map-файл — информация о том по каким адресам в памяти расположены все наши глобальные переменные, функции/процедуры и их локальные переменные. Он генерируется компилятором.
На основании этих данных можно точно найти то что вам нужно.
Получить всю эту информацию в удобном виде можно либо в процессе отладки встроенным в delphi дебагером, либо с помощью компонентов типа EurekaLog, MadExcept, JclDebug и т.п. получать и сохранять в файл отчета об ошибках самой программой, работающей у клиента.
ответ дан 30 мар 2017 в 9:34
Герман БорисовГерман Борисов
10.3k13 серебряных знаков37 бронзовых знаков
Типов сообщений компилятора — более двухсот. Рассмотрим перечень наиболее встречающихся сообщений класса Error
- 0. <Что-то1> expected but <Что-то2> found. Обычно это сообщение возникает при синтаксической ошибке.Например,в случае небаланса скобок,компилятор сообщит: ‘)’ expected but ‘;’ found (вместо ожидавшейся скобки найдена запятая).
Компилятор часто сообщает, что ‘end’ ожидается,например:x:= 5,7; здесь неуместен разделитель-запятая, а сообщается про end. (‘END’ expected but ‘,’ found)
- 1. <Имя> is not a type identifier. Данное <Имя> не является именем типа.
- 2. ‘;’ not allowed before ‘Else’. Перед else нельзя ставить точку с запятой
- 3. Abstract method must be virtual or dynamic. Абстрактный метод должен быть виртуальным или динамическим.
- 4. Ambiguous overloaded call to <Имя блока>. Компилятор не может однозначно выбрать перегружаемый блок. Измените параметр.
- 5. Array type required. Ошибка возникает в случаях, когда в индексе элемента массива указано больше уровней, чем предусмотрено описанием, и если массив не описан. Например, после объявления двумерного массива х или простой переменной х ошибочно записывают элемент х[2,1,1] (в нем показано три измерения).
- 6. Assignment to FOR-loop variable <Имя>. Присваивание значения параметру FOR-цикла в теле цикла.
Например, вследствие описки дважды используется имя i в кратном цикле:
For i:= 1 to n do For i:= 1 to m do ...
- 7. Break or Continue outside of loop. Break или Continue — не в цикле.
- 8. Cannot initialize local variables. Локальные переменные запрещено инициализировать (задавать им значения при описании).
- 9. Cannot assign to/read a read-only/write-only property. Присвоение значения свойству read/only и чтение свойства write/only запрещены.
- 10. Constant expression expected.В этом месте должна стоять константа или константное выражение, например константа выбора в структуре Case.
- 11. Constant expression violates subrange bounds. Выход значения константы из диапазона. Контроль не полон. Например, «сойдет с рук» присваивание x:=3000000000, где х имеет тип integer, но начение х будет искажено.
- 12. Constant or type identifier expected. Требуется имя типа или тип-диапазон.
- 13. Could not compile used unit <Имя>. Компиляция присоединенного модуля <Имя> невозможна.
- 14. Data type too large. Тип определяет структуру размером более 2 Гбайт; это слишком много.
- 15. Declaration expected but <Что-то> found. Пропущено описание или оператор.
- 16. Declaration of <Имя> differs from previous declarations… Данный заголовок блока не соответствует упреждающему объявлению блока.
- 17. Default parameter <Имя> must be by-value or constant. Необязательный параметр (со значением по умолчанию) не должен вызываться по ссылке.
- 18. Expression expected. В этом месте программы должно стоять выражение.
- 19. Expression too complicated. Выражение излишне сложно для компиляции.
- 20. File type not allowed here. В этом месте или в этой роли файловую переменную нельзя использовать. Например, она не может быть формальным параметром-значением.
- 21. For loop control variable must be simple local variable. Параметр цикла должен быть простой локальной (описанной в этом же блоке) переменной.
- 22. For loop control variable must have ordinal type. Параметр цикла должен иметь порядковый тип.Вещественный тип запрещен.
- 23. Function needs result type. В заголовке функции надо указывать тип ее результата.
- 24. Identifier expected but <Что-то> found. В этом месте должно стоять имя. Например, пропущено имя функции после Function.
- 25. Identifier redeclared <Имя>.<Имя> описано повторно, но в пределах блока имя можно описать лишь раз. Проверьте, не обозначена ли локальная переменная тем же именем, что и формальный параметр блока.
- 26. Illegal character in input file <знак>. Запретный знак, например «русская» буква, либо вы оставили скобку }, убрав открывающую скобку {.
- 27. Illegal type in Read/Readln (Write/Writeln) statement. Элемент запрещенного типа в списке ввода/вывода.
- 28. Incompatible types <указание типов>. Несоответствие типов по присваиванию или типов операндов одной операции. Сообщение выдается и при неверном использовании структур. Например, z — запись, ошибочно записано присваивание z:= 0 (работать надо с полями записи).
- 29. Invalid function result type. Недопустимый тип результата функции.
- 30. Label already defined: <Метка>. <Метка> уже помечает другой оператор.
- 31. Left side cannot be assigned to. He может быть такой левой части в присваивании. Примеры: попытка присвоить значение файловой переменной, присвоение значения формальному параметру-константе.
- 32. Line too long. В строке программного текста больше 255 знаков.
- 33. Low bound exceeds high bound. Нижняя граница превышает верхнюю.
- 34. Missing operator or semicolon.Пропуск операции (например перед скобкой) или пропуск точки с запятой. При пропуске ‘;’ маркер ошибки стоит на очередном предложении (объявлении или операторе).
- 35. Missing parameter type. He указан тип формального параметра-значения или параметра процедурного типа.
- 36. Not enough actual parameters. He хватает фактических параметров.
- 37. Need to specify at least one dimension … Нужно задавать в операторе SetLength хотя бы один размер динамического массива.
- 38. Number of elements differs from declaration. Число элементов в структурной константе не соответствует ее описанию.
- 39. Operator not applicable to this operand type. Операция не применима к операндам данного типа. Например: ‘А’ or ‘В’; ‘Text1’* ‘Text2’.
- 40. Order of fields in record constant differs from declaration. Порядок полей в записи-константе не соответствует описанию записи.
- 41. Ordinal type required. Требуется порядковый тип (например, в индексе).
- 42. Out of memory. Компилятору не хватает памяти.
- 43. Statement expected but <Что-то> found. В этом месте должен стоять оператор. Сообщение выдается во всех случаях, когда в тело блока или секцию инициализации ошибочно помещают описание (<Что-то>). Ошибочная форма обращения к процедуре Procedure <Имя> или к функции Function <Имя> также вызывает сообщение.
- 44. Sets may have at most 256 elements. Множество (тип Set) не может содержать более 256 элементов.
- 45. Slice standard function only allowed as open array argument. Функцию Slice можно использовать лишь как фактический параметр
- 46. Statement not allowed in interface part. Предложения в секции интерфейса программного модуля недопустимы.
- 47. Syntax error in real number. Синтаксическая ошибка в записи числа вещственного типа.
- 48. There is no overload version of <Имя> that can be called with these arguments.Не предусмотрен перегружаемый блок <Имя>, который мог бы вызываться с таким аргументом. Пример: IntToStr(x), где х – выражение вещественного типа.
- 49. Too many actual parameters. Фактических параметров больше, чем формальных.
- 50. Type actual and formal var parameters must be identical. Тип фактического параметра должен быть идентичен типу формального параметра-переменной.
- 51. Type of expression must be <Тип>. Выражение должно быть указанного типа. Например,после While и Until должно стоять логическое выражение.
- 52. Undeclared identifier: <Имя>.Не описано <Имя>. Проверьте есть ли описание в нужном месте,нет ли описок в имени. Если указано имя компонента формы, проверьте,поместили ли компонент на данную форму.
- 53. Unexpected end of file in comment started on line <N>. Неожиданный конец файла при незавершенном комментарии, начало комментария — в строке N.
- 54. Unit name mismatch: <Имя>. Имя модуля ошибочно.
- 55. Unsatisfied forward or external declaration <Имя>. Отсутствует описание блока, объявление которого было дано (заголовок в интерфейсе или в описании объектного типа, либо упреждающее описание).
- 56. Unterminate string. He закрыта апострофом строка-константа типа string.
Рассмотрим также некоторые сообщения классов warning и hint.
- Return value of function <Имя> might be undefined. В теле функции нет присваивания ее результата.
- Variable <Имя> might not have been initialized. Указывает имя переменой, которой не задали значения.
- For-Loop variable <Имя> may be undefined after loop. Попытка использования значения параметра For-цикла после завершения этого цикла.
- Text after final ‘END.’ ignored by compiler. Текст, идущий за конечной строкой модуля, игнорируется компилятором.
- Variable <Имя> is declared but never used in <Имя блока>. Обращает внимание на переменную <Имя>, описанную,но не нашедшую применения.
- Value assigned to <Имя> never used. Хотя бы одно значение переменной <Имя> никак не использовано.
Несколько рекомендаций
Сосредотачивайтесь на первом сообщении компилятора. Исправление хотя бы одной ошибки и повторная компиляция может значительно уменьшить число сообщений об ошибках,поэтому не упорствуйте, стремясь понять сразу причину каждого сообщения.
Не удаляйте прежний вариант кода,пока не убедитесь,что ошибка устранена. Лучше на время закомментировать код,заключив его в скобки: { код }
Компилятор не анализирует, как будет выполняться программа, поэтому выход значения индекса из диапазона выявляет только если индекс задан константным выражением. Деление на ноль вообще пропускается, кроме оператора div, в случае если делитель — константное выражение.
0 / 0 / 0 Регистрация: 24.10.2009 Сообщений: 6 |
|
1 |
|
09.10.2013, 18:51. Показов 8470. Ответов 4
Привет всем! Есть код на Delphi 7, программа парсит в инете выбирает информацию. Код довольно большой. Вопрос в следующем как сопоставить адрес ошибки Access violation at address 0048AEC4 in module … read of address 00000000, с конкретной строкой в программе? Теоретически понятно, что где то программа обращается например к элементу массива, за его пределами, но при этом программа не ломается а продолжает выполняться. Так как запросы в инет на получение данных, она шлет по таймеру. Отловить ошибку не представляется возможным, т.к. модуль может работать часами и не сбоить, а может вывалиться, через пару минут. Отсюда вопрос как сопоставить адрес 0048AEC4 с конкретной строкой кода. Если кто в теме откликнетесь, перечитал кучу советов, бьюсь уже кучу времени и отдачи нет. Заранее спасибо!!!
0 |
пофигист широкого профиля 4662 / 3096 / 855 Регистрация: 15.07.2013 Сообщений: 17,855 |
|
09.10.2013, 20:57 |
2 |
Запустить программу под отладчиком, поставив точку останова там, куда процесс обязательно попадет (например на нажатие какой-нибудь кнопки, если в программе есть хотя бы одна кнопка). Когда процесс остановится, открыть меню Делфи -> Search -> Goto Address. В окошко ввести адрес указанный в сообщении об ошибке ($0048AEC4). Ну а затем попытаться развернуть стек вызовов глядя в окошко Call Stack (Меню Делфи -> View -> Debug Windows -> Call Stack. Если это для вас слишком сложно, то есть готовые средства. Например Эврика
2 |
Ivanjulai 0 / 0 / 0 Регистрация: 24.10.2009 Сообщений: 6 |
||||
09.10.2013, 21:20 [ТС] |
3 |
|||
Спасибо! Да чего я и боялся случилось… Предложенным методом нашел, что ошибка возникает в строке:
Которая в свою очередь находится в ComObj.pas из soursertlcommon вот и приехали… Я так понимаю исправить это сложно… Самое странное, что ни к каким видимым ошибкам она не приводит, кроме того, что программа встает колом и если сказать ОК и стартануть программу снова, она продолжает работать…
0 |
пофигист широкого профиля 4662 / 3096 / 855 Регистрация: 15.07.2013 Сообщений: 17,855 |
|
09.10.2013, 21:58 |
4 |
Так как запросы в инет на получение данных, она шлет по таймеру Вот кстати узкое место. Периодический процесс по таймеру с непредсказуемым временем окончания. Проверьте внимательно не может ли где что-то не успевать создаваться или уничтожаться? Или наоборот что-то уже уничтожено а к нему поступает задержавшееся обращение.
1 |
0 / 0 / 0 Регистрация: 24.10.2009 Сообщений: 6 |
|
10.10.2013, 18:42 [ТС] |
5 |
Спасибо, ясно где собака порылась… Хотя вроде логика там верная, таймер запускается, через определенное время, по завершению события DocumentComplit… Ладно главное теперь знаю как найти место ошибки, чего и добивался, еще раз спасибо!!!
0 |