Spec-Zone.ru › Haskell 9

10. Что делать, если что-то пошло не так

Если после ознакомления с этим разделом проблема не исчезла, возможно, вы обнаружили ошибку — сообщите о ней! Подробные сведения о том, как сообщить об ошибке, и список информации, которую мы хотели бы получить о ней, см. в разделе Сообщение об ошибках в GHC. Если сомневаетесь, отправьте сообщение — мы рады письмам от возмущённых пользователей :-!

(Вам также может быть интересен раздел Стандарты Haskell и Glasgow Haskell: несоответствие языковой спецификации, в котором описаны недостатки Glasgow Haskell с точки зрения определения языка Haskell.)

10.1. Когда компилятор «делает что-то не так»

«Помогите! Компилятор аварийно завершил работу (или вызвал панику)!»

Это всегда ошибки в системе GHC — сообщите о них.

«Это ужасное сообщение об ошибке».

Если вы считаете, что GHC мог бы выдать более понятное сообщение об ошибке, сообщите об этом как об ошибке.

«Что означает это предупреждение компилятора C?»

Например: …warning: \`Foo' declared \`static' but never defined. Некрасиво, но проблем возникнуть не должно.

Sensitivity to .hi interface files

GHC очень чувствителен к файлам интерфейса. Например, если он обнаружит нестандартный файл Prelude.hi, последствия могут быть весьма неприятными.

Кроме того, как описано ниже, при запуске программ, скомпилированных с использованием нестабильных интерфейсов, могут возникнуть серьёзные проблемы.

«Мне кажется, GHC генерирует неправильный код»

Маловероятно :-) Полезная опция, позволяющая повысить строгость проверок GHC, — это -dcore-lint-dcore-lint; она запускает проход «lint» для проверки ошибок (в частности, ошибок типов) после каждого прохода преобразования Core-to-Core. Мы всегда используем -dcore-lint; это увеличивает время компиляции примерно на 5%.

Почему возникла ошибка компоновки?

Если компоновщик сообщает, что не может найти _<something>_fast, значит, что-то не согласовано: вероятно, вы скомпилировали модули не в правильном порядке зависимостей.

«Правильно ли указан номер строки?»

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

Пожалуйста, сообщайте об ошибках в номерах строк, которые кажутся вам особенно мешающими.

10.2. Когда ваша программа «делает что-то не так»

(Советы по поводу слишком медленных программ на Haskell или программ, потребляющих слишком много памяти, см. в разделе Советы.)

«Помогите! Моя программа аварийно завершилась!»

(например, возникло «нарушение сегментации» или появилось сообщение «дамп памяти») нарушение сегментации

Если в вашей программе нет вызовов внешних функций и вызовов заведомо небезопасных функций (например, unsafePerformIO), то сбой всегда является ОШИБКОЙ в системе GHC, за исключением одного случая: если программа состоит из нескольких модулей, каждый модуль должен быть скомпилирован после всех модулей, от которых он зависит (если только вы не используете файлы .hi-boot; в этом случае они должны соответствовать исходному коду модуля).

Например, если интерфейс содержит неверную информацию о типе импортированного значения, GHC вполне может сгенерировать неправильный код для импортирующего модуля. Это относится и к прагмам внутри интерфейсов! Если прагма содержит неверную информацию (например, об «арности» значения), результатом может стать неправильный код. Кроме того, арности могут меняться, даже если типы остаются прежними.

Иными словами, если вы скомпилировали модуль и его интерфейс изменился, все модули, импортирующие этот интерфейс, должны быть скомпилированы заново.

Полезная опция, позволяющая узнавать об изменениях интерфейсов, — -ddump-hi-diffs. При изменении файла интерфейса она запускает diff для него до и после изменения, если это применимо.

Если вы используете make, GHC может автоматически сгенерировать зависимости, необходимые для того, чтобы каждый модуль всегда был актуален относительно импортируемых интерфейсов. См. раздел Генерация зависимостей.

Если вы готовите последнюю перед сообщением об ошибке компиляцию, рекомендуем добавить опцию -dcore-lint (для дополнительной проверки) к параметрам компиляции.

Поэтому, прежде чем сообщать об ошибке из-за дампа памяти, вам, вероятно, следует:

% rm *.o        # scrub your object files
% make my_prog  # re-make your program; use -ddump-hi-diffs to highlight changes;
                # as mentioned above, use -dcore-lint to be more paranoid
% ./my_prog ... # retry...

Разумеется, если в вашей программе есть вызовы внешних функций, ничто не гарантировано: вы можете повредить кучу, стек или что угодно ещё.

«Моя программа обратилась к аргументу, помеченному как отсутствующий».

Это определённо вызвано ошибкой в GHC. Пожалуйста, сообщите о ней (см. раздел Сообщение об ошибках в GHC).

«Что это за арифметическая (или плавающая) ошибка?»

Арифметические операции Int, Float и Double выполняются без проверки. Переполнения, потеря значимости и точности либо остаются незамеченными, либо сообщаются операционной системой как исключение (в зависимости от платформы). Деление на ноль может вызвать необработанное исключение (если это произойдёт, пожалуйста, сообщите об этом).

© 2002–2007 The University Court of the University of Glasgow. All rights reserved.
Licensed under the Glasgow Haskell Compiler License.
https://downloads.haskell.org/~ghc/9.14.1/docs/users_guide/gone_wrong.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API