|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Уважаемые форумчане, доброго дня. Столкнулся с проблемой : Проект : Delphi XE + FireBird. Использую в программе динамическую библиотеку, которую сам же и разрабатываю. Код вызова библиотеки : Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Код обработки при выгрузке DLL : Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37.
Суть вопроса : Если при вызове DLL в обработчика срабатывает exception, который посылает FireBird (обработка хранимых процедур и вызов внутри процедуры) Код: plsql 1. 2. 3.
, то при завершении работы с DLL исполняемая программа зависает. Заметил одну особенность поведения программы при вызове исключения : Код: pascal 1. 2.
Создается отдельный поток, который потом при DLL_PROCESS_DETACH не убивается. Что делать в данной ситуации? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 13:23 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Забыл добавить, что если не срабатывает exception, то DLL выгружается без проблем. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 13:25 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Kirill Lagunov, Эксепшены, старты/убийства потоков и еще много чего - плохой стиль, а иногда и невозможно делать в DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH. Об этом написано в MSDN, не хочется искать опять. Сделай доп. две экспортируемые из длл функции Initialize/Finalize, которые и вызывай при успешном LoadLibrary. В них всё делай. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 13:32 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Kirill Lagunov, Да, забыл добавить. Выпускать из dll эксепшены наружу - тоже не очень стиль :) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 13:34 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
YuRock, Суть то в том, что эти эксепшены FB-шные я не создаю в DLL, они обрабатываются на стороне сервера, а потом посылаются в программу. Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
И, по сути, поток я тоже не создаю в DLL. На счет Initialize/Finalize вне DLL почитаю, но вопрос немного в другом =) ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 13:39 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Kirill LagunovСуть то в том, что эти эксепшены FB-шные я не создаю в DLL Kirill LagunovИ, по сути, поток я тоже не создаю в DLL Ты создаешь. Модули, которые ты используешь (например, которые работают с клиентской библиотекой FB) - это такая же "твоя программа", как и лично твой код. Бинарник отличий не видит. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 13:51 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Kirill Lagunov Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Этот странный код только в каких-то единичных случаях может не привести к тому, что исключение не попадет "наружу". Если, например, транзакция не активна, то сначала будет исключение на Commit, а затем и в обработке этого исключения - на Rollback, и это второе исключение ты уже не обрабатываешь. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 13:54 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
YuRockKirill Lagunov Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Этот странный код только в каких-то единичных случаях может не привести к тому, что исключение не попадет "наружу". Если, например, транзакция не активна, то сначала будет исключение на Commit, а затем и в обработке этого исключения - на Rollback, и это второе исключение ты уже не обрабатываешь. Проверка на активность транзакции выше по коду в процедуре. Код: pascal 1. 2. 3.
YuRockKirill LagunovСуть то в том, что эти эксепшены FB-шные я не создаю в DLL Kirill LagunovИ, по сути, поток я тоже не создаю в DLL Ты создаешь. Модули, которые ты используешь (например, которые работают с клиентской библиотекой FB) - это такая же "твоя программа", как и лично твой код. Бинарник отличий не видит. Это я понимаю, имел в виду, что не создаю их вручную. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 14:02 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Kirill LagunovПроверка на активность транзакции выше по коду в процедуре. Мало ли какие там ошибки ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 14:59 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
YuRockKirill LagunovПроверка на активность транзакции выше по коду в процедуре. Мало ли какие там ошибки Ошибка явная, обработка исключения при вызове хранимой процедуры, которая передает код и текст исключения. Вопрос тогда такой, как можно поток с этим исключением отловить и завершить, либо как при выгрузке DLL закрыть все потоки, созданные при вызове DLL? ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 15:06 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Kirill Lagunov, в DLL не должно возникать никаких exception, следует начинку каждой экспортируемой функции обернуть в try .. except и возвращать код ошибки. А если интересен и текст ошибки, то тут несколько вариантов: 1) либо добавить еще одну функцию, например GetLastErrotText, 2) либо через параметры функции ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 15:08 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Код: pascal 1.
Вы обмениваетесь объектами Delphi через границе модулей. Нафига вам тогда DLL? Делайте пакет, сплошные плюсы: - Нет проблем с DllMain, у пакетов инициализация/финализация вынесена в изолированные функции - Нет проблем с исключениями через границы модулей, у пакетов вызываемый и вызывающий написаны на одном языке - Нет проблем с передачей памяти и не нужны костыли, пакеты всегда неявно используют разделяемый менеджер памяти - Экономится место, общий код вынесен в RTL/VCL пакеты ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 15:18 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Попробуйте в длл при выгрузке дернуть Код: pascal 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 15:34 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Kirill LagunovОшибка явная, обработка исключения при вызове хранимой процедуры, которая передает код и текст исключения. Ну так обработай её таким образом, чтобы при обработке не могло возникнуть еще одного исключения. Kirill LagunovВопрос тогда такой, как можно поток с этим исключением отловить и завершить Вручную и больше никак. TIBDatabase потоки не порождает, на сколько мне известно. Разве что TIBEvents.RegisterEvents И делать это надо (потоки останавливать, все объекты освобождать и т.д.) в доп. функции Finalize, о которой я выше писал. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 15:54 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
YuRockTIBDatabase потоки не порождает, на сколько мне известноТы ошибаешься. Курить IBSQLMonitor.pas ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 16:37 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
_Vasilisk_, Если мониторинг включен, то да. А по умолчанию он выключен (TraceFlags=[]), как и эвентов по умолчанию нет. ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 17:32 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
YuRockА по умолчанию он выключенУгу. Вот только он имеет свойство включаться Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69.
... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 17:43 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
_Vasilisk_, Да, красиво, конечно. Но до такого не должно доходить. Я сейчас специально потестил. В TWriterThread.Execute и TReaderThread.Execute в отладке попадаю, только если TIBDatabase.TraceFlags <> []. Делал connect, starttransaction, execsql, fetch, commit... Дальше разбираться лень. Да и если б это было так, у меня б все dll-ки, создающие внутри TIBDatabase, за всю жизнь написанные, некорректно выгружались бы, с проблемами из-за не остановленных потоков. А этого нет и не было никогда. Только если TIBDatabase не освободить - бывают проблемы (тоже разбираться лень, почему, ведь освобождать всё равно надо). ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 18:08 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
YuRockв отладке попадаю, только если TIBDatabase.TraceFlags <> []. Делал connect, starttransaction, execsql, fetch, commit...Выполни ExecSQL, но чтобы оператор поднял ошибку. Что-то типа Код: sql 1. 2. 3. 4. 5.
Код: pascal 1. 2.
Или сделай какую нибудь вставку, приводящую к двойным уникальным ключам YuRockДа и если б это было так, у меня б все dll-ки, создающие внутри TIBDatabase, за всю жизнь написанные, некорректно выгружалисьЯ на такое наткнулся в своем COM-сервере. Если с сервера приходит ошибка (т.е. вызывается IBDataBaseError), то приложение не выгружалось. Несмотря на то, что исключение перехватывалось и обрабатывалось ... |
|||
:
Нравится:
Не нравится:
|
|||
06.11.2017, 18:32 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
GunSmoker Код: pascal 1.
Вы обмениваетесь объектами Delphi через границе модулей. Нафига вам тогда DLL? Делайте пакет, сплошные плюсы: - Нет проблем с DllMain, у пакетов инициализация/финализация вынесена в изолированные функции - Нет проблем с исключениями через границы модулей, у пакетов вызываемый и вызывающий написаны на одном языке - Нет проблем с передачей памяти и не нужны костыли, пакеты всегда неявно используют разделяемый менеджер памяти - Экономится место, общий код вынесен в RTL/VCL пакетыНадо не пакеты, надо один пакет. Один bpl, а то много файлов выходит: vcl.bpl, rtl.bpl, forms.bpl, winapi.bpl и т.д. И чтобы он был встроен в exe, желательно. Чтоб глаза не видели и не осозновать. Я бы загулял: маленькие .dll-ки к программе, а в них по сути целые формы. Одним чертом либы пишутся специально под приложение, да и 20MB экзешник перекомпилировать каждый раз если не распилить на dll. У меня нет SSD. try finally FreeLibrary(DLLHandle); end; ^Finally значит что либа будет выгружена вне зависимости от того был ли exception. Зачем её вообще загружать тогда? Не ради же вызова какой-нибудь функции каждый раз. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2017, 04:39 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
GunSmoker Код: pascal 1.
Вы обмениваетесь объектами Delphi через границе модулей. Нафига вам тогда DLL? Делайте пакет, сплошные плюсы: - Нет проблем с DllMain, у пакетов инициализация/финализация вынесена в изолированные функции - Нет проблем с исключениями через границы модулей, у пакетов вызываемый и вызывающий написаны на одном языке - Нет проблем с передачей памяти и не нужны костыли, пакеты всегда неявно используют разделяемый менеджер памяти - Экономится место, общий код вынесен в RTL/VCL пакеты Из описания пакетов При использовании пакетов необходимо вкладывать в дистрибутив приложения все пакеты, на которые ссылается разрабатываемый вами пакет. Если это утверждение верное, то такой вариант мне не особо подходит. Библиотека делается для того, чтоб при изменениях не нужно было пересобирать основной проект. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2017, 10:05 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Кар-КарGunSmoker Код: pascal 1.
Вы обмениваетесь объектами Delphi через границе модулей. Нафига вам тогда DLL? Делайте пакет, сплошные плюсы: - Нет проблем с DllMain, у пакетов инициализация/финализация вынесена в изолированные функции - Нет проблем с исключениями через границы модулей, у пакетов вызываемый и вызывающий написаны на одном языке - Нет проблем с передачей памяти и не нужны костыли, пакеты всегда неявно используют разделяемый менеджер памяти - Экономится место, общий код вынесен в RTL/VCL пакетыНадо не пакеты, надо один пакет. Один bpl, а то много файлов выходит: vcl.bpl, rtl.bpl, forms.bpl, winapi.bpl и т.д. И чтобы он был встроен в exe, желательно. Чтоб глаза не видели и не осозновать. Я бы загулял: маленькие .dll-ки к программе, а в них по сути целые формы. Одним чертом либы пишутся специально под приложение, да и 20MB экзешник перекомпилировать каждый раз если не распилить на dll. У меня нет SSD. try finally FreeLibrary(DLLHandle); end; ^Finally значит что либа будет выгружена вне зависимости от того был ли exception. Зачем её вообще загружать тогда? Не ради же вызова какой-нибудь функции каждый раз. Кар-Кар^Finally значит что либа будет выгружена вне зависимости от того был ли exception. Странное заявление, ведь если бы библиотека выгружалась вне зависимости от того, был ли exception или нет, я бы сюда не писал =) И, естественно, не для вызова одной функции это делается. Проект достаточно большой, так сказать,кол-во конечных пользователей с каждым днем растет, есть разные отделы, у которых специфичные потребности к программе, а каждый раз пересобирать основной проект нет желания, т.к он в себе, по сути, держит все основные классы, функции, для работы штатного сотрудника и так же все сделано для внедрения динамических библиотек (обновление/проверки хеша и т.д) ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2017, 10:09 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
_Vasilisk_YuRockTIBDatabase потоки не порождает, на сколько мне известноТы ошибаешься. Курить IBSQLMonitor.pas Проблема оказалась слишком смешной, действительно, есть бага в IBSQLMonitor. Решилось все очень просто : Код в DLL Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Источник ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2017, 12:09 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Kirill Lagunov Код: pascal 1.
Я сталкивался с тем, что несмотря на вызов DisableMonitoring по загрузки библиотеки, в некоторых случаях он все равно включался. Разбираться из-за чего было лень, поэтому у меня DisableMonitoring вызывается дважды - в начале работы и в конце ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2017, 17:10 |
|
Обработка exception в DLL
|
|||
---|---|---|---|
#18+
Тоже посчастливилось столкнуться к подобным глюком в IBSQLMonitor (D2007). У меня проблема выглядела следующим образом: если при попытке выполнить TIBDataSet.Connection := True (из доп. потока) возникает ошибка (например, Firebird выключен), то это штука лезла зачем-то в основной поток, а основной поток в свою очередь тоже висел на вызове TIBDataSet.Connection := True. В результате - взаимоблокировка. Долго не мог разобраться. Воспроизводится только на рабочем проекте. DisableMonitoring решил проблему. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.02.2022, 11:36 |
|
|
start [/forum/topic.php?fid=58&msg=39548477&tid=2036605]: |
0ms |
get settings: |
21ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
75ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
502ms |
get tp. blocked users: |
1ms |
others: | 381ms |
total: | 1017ms |
0 / 0 |