Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Delphi: Общие вопросы > Не срабатывает breakpoint |
Автор: LamerTM 25.11.2008, 19:45 |
Стоит Delphi 7. В одной из программ не срабатывает Breakpoint. Вообще. В чем может быть причина? В других прогах срабатывает (напр. если новый проект сделать, кинуть кнопку на форму, поставить брейк в buttonclick, то при нажатии на кнопку он сработает). |
Автор: AKATAN 25.11.2008, 20:57 |
Значит данный кусок кода не выполняется. Приведите пример, и по возможности скрин того, как Вы ставите брейкпоинт. |
Автор: Bose 25.11.2008, 21:01 |
Проект должен быть скомпилирован с включением отладочной информации. Project->Options->Compiler Здесь должны быть включены галочки: Debug information, Local symbols, Reference info, Definitions only, Assertions. А галочка Optimization должна быть выключена. |
Автор: AKATAN 25.11.2008, 21:29 |
На счет вышесказанного все верно. Но не уверен что включение галочки Optimization будет влиять на отладку. Оптимазиция касается бинарного в не исходного кода. |
Автор: THandle 25.11.2008, 21:35 | ||||
AKATAN, ну а попробовать? ![]() Возьмем самый простой пример:
Поставим бряк на строку с присвоением переменной i числа 5. При отладке эта строчка будет пропущена. А теперь попробуем так:
При отладке строка не пропускается... |
Автор: LamerTM 25.11.2008, 21:47 |
В проекте несколько форм. Соответственно несколько модулей. Брейкпоинт работает во всех модулях кроме одного. Не работает только в unit5. Проявляется это по-разному. Например, если поставить брейкпоинт в процедуру FormCreate и запустить прогу по F9, то после компиляции (т.е. уже во время работы программы) картинка становится такой: http://ipicture.ru/ Код FormCreate отрабатывает. Это установлено однозначно, потому что появляется messagebox. Брейкпоинт не срабатывает (хотя по картинке и не должен, но почему он такой цвет имеет ?) Если поставить брейкпоинт в другой процедуре того же модуля, и запустить прогу (F9), то после компиляции картинка такая: http://ipicture.ru/ При нажатии кнопки, соответствующей этой процедуре, этот код запускается, что видно по появляющемуся messagebox. Но брейкпоинт не срабатывает. Цвет полоски брейкпоинта остается таким же как на картинке. Насчет настроек Project->Options->Compiler. Все галочки установлены как надо. |
Автор: Bose 25.11.2008, 22:33 | ||
Возможно, компилятор всё-таки использует dcu-шки без отладочной ифнормации. Попробуй, сделать принудительный Build: Project->Build project. |
Автор: AKATAN 25.11.2008, 22:51 |
THandle, спасибо. Точно. Че-то не стыкался с подобным. Хотя возникнуть может такое лишь в довольно кривом коде. На счет брейкпоинтов. Хм... Данный цвет брейкпоинта (блевотно-зеленый, что-ли =) ) обозначает, что он - "unreachable breakpoint" (недосягаем) Может все дело в многопоточности? Возможно данный код исполняется раньше, чем до него доходит отладчик, который шустрит другой поток... Хотя это лишь предположение. У меня такое встречалось. Решал, либо вставкой мусорного кода, либо немного переделывал сам код... |
Автор: LamerTM 25.11.2008, 22:54 | ||||
Не сработало. Пробовал удалить dcu - тоже не помогает. Скопировал проект на другой комп (там тоже delphi 7 установлена) - тот же результат. То есть дело в проекте (а то я тут уже делфи пару раз сносил и устанавливал. ![]() Добавлено @ 23:04
Я многопоточность не использую. Потому что не знаю как её использовать. ![]() Сейчас я сделал так. В файле .dpr есть команда Application.CreateForm(TForm5, Form5); Она вызывает понятно какую процедуру (скрин её я приводил). Я поставил брейкпоинт прямо на эту команду в модуле .dpr Результат: брейкпоинт сработал (потому что он везде работает кроме unit5). Дальше я нажал F7 чтобы зайти в Unit5.FormCreate. И получил ошибку Access Violation. Если вместо F7 нажать F8, то ошибок никаких нет. (При простом запуске программы тоже нет ошибок) Окно ошибки было такое: в заголовке: "Debugger Exception Notification" Текст в окне: "Project <имя exe-файла> raised exception class EAccessViolation with message 'Access violation at address 0052E05D in module '<имя exe-файла>'. Write of address 01960A14. Process stopped. Use Step or Run to continue." Полоска дебагера (которая указывает на текущую команду) оказалась в какой-то левой процедуре в unit5, которая в это время никак выполняться не могла. |
Автор: LamerTM 26.11.2008, 00:09 |
Я тут подумал, а может быть причиной глюка большой размер исходного кода модуля? Он у меня 794 КБ. Когда был 750Кб все работало нормально (у меня старая версия сохранена, там всё ОК). |
Автор: AKATAN 26.11.2008, 00:42 | ||
Не думаю. У меня бывали сорцы и по пару метров. А то что ты не юзаешь многопоточность, не значит, что процесс имеет всего один поток. Возможно ты используешь всякие stream'ы (Например filestream...) что сами по себе создают свои потоки. Это легко проверить с помощью проги ProcesXP (http://www.sysinternals.com/). Она покажет все процессы, потоки, семафоры, мютексы и прочий бред. Скачай, запусти приложение и посмотри. Мне аж самому интересно стало... ![]() |
Автор: Akella 26.11.2008, 09:28 | ||
Будет. Если Выключена, то нужно включить и обязательно перекомпилировать весь проект. |
Автор: CodeMonkey 26.11.2008, 10:10 |
1. Можете переместить код AbortButtonClick рядом к FormCreate, сделать Build, а потом - скриншот этих двух процедур? Хочу посмотреть на синие точки. Бряки ставить не обязательно. 2. Проверьте, что стоит у формы в её FormCreate в инспекторе объектов. 3. Проверьте ещё вот это: http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=1025. |
Автор: LamerTM 26.11.2008, 11:02 | ||
1. Вот: http://ipicture.ru/ Синих точек нет (я сделал всё правильно: переместил код AbortButtonClick и нажал Build Project). Их нет вплоть до 6058 строки. С 6059 строки и ниже они есть. Если ставить бряк туда где нет синих точек, то он становится с крестиком и не срабатывает. Если где есть синие точки - тогда с галочкой. После того как переставил процедуру AbortButtonClick бряки с галочкой стали срабатывать, но при этом выдается ошибка AccessViolation. Вот такая: --------------------------- Debugger Exception Notification --------------------------- Project aaa.exe raised exception class EAccessViolation with message 'Access violation at address 00406384 in module 'aaa.exe'. Write of address 0000000A'. Process stopped. Use Step or Run to continue. --------------------------- OK Help --------------------------- 2. Стоит имя процедуры FormCreate. 3. Что-то похожее, но у меня по-другому. У меня до 6058 строки синих точек нет вообще, а ниже они стоят четко напротив нужных команд (не напротив пустых строк или коментов). |
Автор: CodeMonkey 26.11.2008, 11:14 | ||
В другой версии Delphi не пробовали? Попробуйте поставить бряк руками:
Что будет? Добавлено через 1 минуту и 23 секунды ...и попробуйте ещё включить Use Debug DCU, сделать Build и повторить http://forum.vingrad.ru/index.php?showtopic=237682&view=findpost&p=1708843. |
Автор: LamerTM 26.11.2008, 11:59 | ||||
В другой версии Delphi не пробовал. Поставил asm int 3 end в FormCreate. Результат: остановка программы; полоска дебагера в какой-то левой процедуре модуля unit5. При нажатии F7 получается AccessViolation. Потом проект перезагрузил (чтобы убрать изменения). Включил Debug DCU's. Поставил бряк в файл .dpr на команду Application.CreateForm(TForm5, Form5); Запустил прогу по F9. Бряк сработал. Нажал F7. Попал в модуль Forms в процедуру: procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference); Стал нажимать F8 и F7. Дошел до места вызова FormCreate. Попал в левую процедуру unit5 (ту же самую, куда попадал когда ставил asm int 3 end). Уже в этой левой процедуре нажал F7. Попал в процедуру MessageDlg (хотя команда была совсем другая на экране написана. Но первая строка в FormCreate была вызовом MessageDlg). Короче, на экране нарисовано одно, а выполняется другое. Потом после MessageDlg опять AccessViolation случился. Если переставлять процедуры в unit5, то синие точки появляются начиная с разных мест. Что-то мне это стало надоедать уже. ![]() |
Автор: CodeMonkey 26.11.2008, 12:18 |
А большой проект? Может выложите? Для интересу. |
Автор: LamerTM 26.11.2008, 12:42 | ||
К сожалению выложить не могу. |
Автор: LamerTM 26.11.2008, 12:58 | ||
Написал небольшую прогу чтобы она прошлась по исходнику в поисках 0D без 0A. Не нашла. |
Автор: CodeMonkey 26.11.2008, 13:27 | ||||
А можно тогда скрин? |
Автор: Bose 26.11.2008, 13:54 | ||
У меня было что-то похожее, когда в программе было много извращений с {$IFDEF} {$ENDIF} и часть кода была вынесена в included файлы. |
Автор: LamerTM 26.11.2008, 14:16 | ||||||
Если в FormCreate поставить 'asm int 3 end' вот так (картинка сразу после build project): http://ipicture.ru/ То при старте приложения по F9 дебагер останавливается в этом месте: http://ipicture.ru/ Эта процедура в реальности не выполняется. |
Автор: CodeMonkey 26.11.2008, 15:17 |
Реально странная загадка. Если это не проблема с DCU, то я даже и не знаю. А CPU отладчиком умеете пользоваться? Может посмотреть куда идёт CALL из TApplication.CreateForm? И сравнить его с указателем на TForm5.FormCreate. |
Автор: LamerTM 26.11.2008, 16:57 | ||
CPU я не очень умею пользоваться. Но попробую. В процедуру TForm5.FormCreate поставил вызов MessageDlg. Вот так: http://ipicture.ru/ Потом сделал как и раньше: бряк на Application.CreateForm в модуле .dpr Запустил по F9. Бряк сработал. Включил CPU Window. И стал нажимать F7 и F8. Пока не дошел до TForm5.FormCreate. Скрин CPU в этот момент (я тут уже немного вперед прошел): http://ipicture.ru/Gallery/Viewfull/9579216.html Видно, что асмовский код соответствует паскалевскому коду FormCreate. А строки паскалевские из левой процедуры. В окне паскалевского исходника полоска дебагера тоже в левой процедуре. При трассировке CPU выполняется код FormCreate (вызывается MessageDlg и т.д. Без ошибок всё). При этом полоска дебагера (что в code editor, где паскалевский исходник) скачет черт знает где по исходнику, только не там где реально выполняется программа. |
Автор: CodeMonkey 26.11.2008, 17:27 |
А если вызвать AOF_L2 по F7 (хотя бы в том же TForm5.FormCreate, вместо диалога), то что покажет CPU-отладчик? |
Автор: LamerTM 26.11.2008, 17:34 | ||
А её нельзя вызвать напрямую. Она объявлена внутри другой процедуры. Думаю, если извратиться и вызвать, то полоска дебагера окажется в какой-нибудь другой процедуре. ![]() |
Автор: CodeMonkey 26.11.2008, 17:43 |
Мож попробуем извратиться? ![]() Кстати, если просто по-процедурно перетащить код из Unit5 в новый Unit5 ничего не меняется? |
Автор: LamerTM 26.11.2008, 18:01 | ||||||||
А смысл? Я сейчас AOF_L2 передвинул вниз по тексту. Стало останавливаться в другой процедуре, но в том же месте (раньше останавливалось на строке 8648 исходника, и теперь на 8648, только процедура там теперь другая).
Если открыть глючный Unit5 в блокноте, нажать Ctrl+A, потом Ctrl+C. Потом в Delphi открыть старую версию проекта (с безглючным Unit5), выбрать Unit5, нажать Ctrl+A, потом Ctrl+V. Потом сделать Build Project , то получаются всё те же глюки (то есть нет синих точек в начале текста, не работают брейки и т.д.). Насчет перетаскивать по-процедурно - сейчас этим и займусь. Буду в старую версию перетаскивать из новой глючной версии только новые процедуры. И смотреть на какой из них заглючит весь модуль. ![]() Добавлено @ 18:03
У меня в проблемном Unit5 нет ни одного IFDEF. В других модулях есть, но мало.
Интересно, а как можно вытащить указатель на процедуру на глобальный уровень? Это потом даст возможность вызывать локальные процедуры? |
Автор: CodeMonkey 26.11.2008, 18:23 | ||||
Не очень красиво (и совершенно идейно неправильно), но можно как-то так:
См. также: http://forum.sources.ru/index.php?showtopic=248820 А вот интересно, если код FormCreate IDE считает за код AOF_L2, то за что будет она считать код самой AOF_L2? По типу, это какой-то странный сдвиг строк вдруг произошёл или ещё что-то... Добавлено через 1 минуту и 11 секунд А какой размер в строках/байтах имеет этот модуль? |
Автор: LamerTM 26.11.2008, 18:49 | ||||
На AOF_L2 свет клином не сошелся. Она просто оказалась в нужное время в нужном месте, то есть на строке 8648 исходника. Если туда поставить другую процедуру - остановится в ней. Вот я сейчас сдвинул вниз AOF_L2 и ту что была выше её. Запустил - в результате остановка произошла вообще в середине предыдущей процедуры. Но только на строке 8677. Да и на AOF_L2 оно останавливалось не в начале процедуры. Наверное оно количество строк с синими точками остчитывает. Если поставить в первую строку AOF_L2 команду 'asm int 3 end', потом в программе нажать кнопки так чтобы запустилась AOF_L2, то остановка сразу вываливает в CPU-Window, при этом полоски дебагера в паскалевском редакторе нет. Скрин: http://ipicture.ru/Gallery/Viewfull/9582919.html Видно, что адрес AOF_L2 установлен правильно, а паскалевская строка (if nb[0] then...) - левая, имеет номер 13107, хотя AOF_L2 находится в районе 8648 строки. При трассировке по F7 в CPU-Window прога выполняется и курсор дебагера (не знаю как правильно он называется) иногда появляется в редакторе кода, а потом снова исчезает. Появляется он в самом конце текста, не на реально выполняемом коде. А изчезает, видимо, когда хочет появиться вообще вне текста.
Размер в байтах я не знаю как узнать. Размер в строках исходника - 21574 строк. Размер файла Unit5.pas 794КБ. |
Автор: CodeMonkey 26.11.2008, 19:06 |
Ого, 800 Кб текста! Похоже на какой-то глюк компилятора из-за большого размера модуля. Попробуйте тупо разделить модуль пополам, и вторую половину вынести в inc-файл. Ещё я бы включил генерацию map-файлов в опциях проекта и сравнил бы получившийся map-файл с тем, что мы сейчас видим под отладчиком. Добавлено через 5 минут и 47 секунд P.S. А когда такое стало происходить? Раньше нормально работало или как? |
Автор: LamerTM 26.11.2008, 19:43 | ||||
Тут писали что у кого-то и по 2МБ исходники были. Я не знаю что такое inc-файл (я же ламер! ![]()
Да, раньше всё работало. Я пишу прогу и периодически сохраняю текущее состояние в отдельный архив. Последние порядка 15 процедур я написал без дебагера. Когда он понадобился, оказалось что всё глючит. |
Автор: LamerTM 26.11.2008, 20:21 | ||
В модуле есть массив:
Глюки начинаются когда количество элементов массива становится больше 132. Если просто скопировать этот массив в чистый проект, то глюк не появляется. ![]() |
Автор: Bose 26.11.2008, 21:39 | ||
есть предположение:
TTElemInfo содержит строки? Такая проблема может появится если какая-нибудь из строк будет содержать недопустимые символы, которые IDE не умеет обрабатывать: только $0A или только $0D, например. |
Автор: LamerTM 26.11.2008, 22:16 | ||||||
Да, TTElemInfo содержит строки.
Я поубирал некоторые особенно длинные строки и глюк исчез. ![]()
Искал программой только $0A и только $0D - не находит. Дело в другом, видимо. |
Автор: LamerTM 26.11.2008, 23:32 |
Перенес массив в другой модуль, где меньше кода, и глюк исчез. Еще одно открытие: в Unit5 много всяких деклараций (типов, констант). Если их часть перенести в другой модуль, то глюк исчезает без переноса массива. Так что похоже проблема в слишком большом объеме объявлений типов и констант. |
Автор: CodeMonkey 27.11.2008, 10:21 |
Ну, вот, похоже, что это действительно глюк IDE, связанный с большим объёмом исходника. А может быть, даже не с объёмом, сколько с его видом. Как http://transl-gunsmoker.blogspot.com/2008/11/internal-error-delphi.html, например. Тогда всего-то нужно лучше структурировать программу. P.S. Вынесение в inc-файл выполняется так: создаётся пустой текстовый файл с любым расширением, но обычно используют ".inc". В него пишется любой текст, в частости можно перенести текст из pas-модуля. Затем в то место, где нужно вставить этот текст, в pas-модуль добавляется "{$I имя-файла.inc}" (с относительным путём поиска, если он нужен). Тогда компиялтор считает, что в pas-модуле как буд-то вместо этой директивы написан текст самого inc-файла. |
Автор: LamerTM 27.11.2008, 11:07 | ||
Я пробовал увеличивать размер кода в модуле. Глюк не возникает. (добавлял лишние огромные процедуры с их вызовом) А вот от увеличения части где объявляются типы и константы глюк возникает. Вынос массива или части кода в inc-файл проблемы не решает - глюк остается. Добавлено @ 11:12 Мне удалось воссоздать глюк в чистом проекте! Для этого скопировал все объявления типов и констант из своего проекта. |
Автор: LamerTM 27.11.2008, 11:46 | ||||
Как сделать такой глюк в Delphi 7. Надо нажать File -> New -> Applicaition На форму кинуть кнопку TButton и Memo. В Memo сделать ScrollBars видимыми. В событии OnClick Button1 написать такой код:
Запустить Project1 по F9. Нажать в нем кнопку. Содержимое Memo выделить и скопировать в буфер по Ctrl+C. Закрыть Project1. Зайти в редактор кода проекта. После раздела uses написать слово const и вставить Ctrl+V так чтобы получилось так:
После этого поставить бряк на первую строку Button1Click. Нажать F9. У меня в D7 бряк не срабатывает. |
Автор: CodeMonkey 27.11.2008, 12:39 |
Что-то очень похожее: http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=612 |
Автор: CodeMonkey 27.11.2008, 12:57 |
D2007 - работает отлично. |
Автор: LamerTM 27.11.2008, 14:41 | ||
В Delphi 2005 глючит. А D2007 у меня нет. |
Автор: vkhacker 30.4.2010, 00:49 |
У меня практически та же картина: один из модулей не отлаживается. Размер: меньше 2000 строк. С остальными модулями все отлично. Не знаю в чем дело. |
Автор: CodeMonkey 30.4.2010, 11:24 |
И чо? |