Я делаю низкоуровневое IO (для привязки к библиотеке) в Haskell и испытываю segfault. Я хотел бы использовать GHCi : break, чтобы выяснить, что происходит, но вот что происходит:
> import SDL
> :break SDL.setPaletteColors
cannot set breakpoint on setPaletteColors: module SDL.Video.Renderer is not interpreted
Так как код нарушения не находится внутри моих собственных модулей, а скорее внутри модуля во внешнем пакете, он загружается как скомпилированный код и, по-видимому, я не могу использовать : break на скомпилированных модулях.
Руководство GHCi подтверждает это и дает подсказку:
Существует одно основное ограничение: точки останова и одноэтапный доступ доступны только в интерпретируемых модулях; скомпилированный код невидим для отладчика [5].
[5] Обратите внимание, что пакеты содержат только скомпилированный код, поэтому отладка пакета требует непосредственного поиска его источника и загрузки.
Попробуйте прямо:
> :load some_path/sdl2/src/SDL/Video/Renderer.hs
some_path/sdl2/src/SDL/Video/Renderer.hs:101:8:
Could not find module ‘Control.Monad.IO.Class’
It is a member of the hidden package ‘transformers-0.3.0.0’.
Perhaps you need to add ‘transformers’ to the build-depends in your .cabal file.
Use -v to see a list of the files searched for.
Я могу добавить зависимости к моему .cabal файлу, но это уже кажется неправильным. Как только я это сделал:
> :load some_path/sdl2/src/SDL/Video/Renderer.hs
some_path/sdl2/src/SDL/Video/Renderer.hs:119:8:
Could not find module ‘SDL.Internal.Numbered’
it is a hidden module in the package ‘sdl2-2.0.0’
Use -v to see a list of the files searched for.
Я мог бы сделать эти модули общедоступными (возможно, изменив пакет .cabal?), но на данный момент это кажется очень неудобным способом делать что-то, и я не преследовал его дальше.
EDIT:
Я действительно попробовал это и получил озадачивающий результат:
> :load some_path/sdl2/src/SDL/Video/Renderer.hs
[1 of 1] Compiling SDL.Video.Renderer ( some_path/sdl2/src/SDL/Video/Renderer.hs, interpreted )
Ok, modules loaded: SDL.Video.Renderer.
> :break SDL.setPaletteColors
cannot set breakpoint on SDL.setPaletteColors: module SDL.Video.Renderer is not interpreted
Моя (необразованная) догадка: это потому, что внешний модуль по-прежнему связан с моим кодом как двоичный код, а динамическая загрузка в интерпретируемом режиме не меняет этого.
Итак, чтобы подытожить вопрос:, что является хорошим способом отладки IO во внешнем пакете?
Дополнительные примечания:
-
У меня есть источник для пакета, который мне нужно отлаживать; Фактически, он был добавлен в проект с дополнительным источником песочницы cabal
-
Альтернативный вариант использования GHCi заключается в добавлении трассировок в исходный код пакета, но это неудачный вариант, поскольку он предполагает перекомпиляцию пакета при каждой модификации (всякий раз, когда мне нужна дополнительная информация о выполнении и изменении следы), и это занимает очень много времени. Интерактивная отладка с GHCi кажется лучшим инструментом для этой работы, если только я знал, как ее использовать.