Глава 13 Система выполнения (ocamlrun)
Команда ocamlrun выполняет файлы байткода, созданные на стадии компоновки командой ocamlc.
13.1 Обзор
Команда ocamlrun состоит из трёх основных частей: интерпретатора байткода, который фактически выполняет файлы байткода; менеджера памяти и сборщика мусора; и набора функций C, которые реализуют примитивные операции, такие как ввод/вывод.
Использование ocamlrun:
ocamlrun options bytecode-executable arg1 ... argn
Первый аргумент, не являющийся параметром, принимается как имя файла, содержащего исполняемый байткод. (Этот файл ищется в пути к исполняемым файлам, а также в текущем каталоге.) Остальные аргументы передаются программе OCaml в массиве строк Sys.argv. Элемент 0 этого массива — имя файла исполняемого байткода; элементы с 1 по n — это оставшиеся аргументы arg1 до argn.
Как упоминалось в главе 11, файлы исполняемого байткода, созданные командой ocamlc, являются самозапускаемыми и автоматически запускают команду ocamlrun на себе. То есть, если a.out — это файл исполняемого байткода,
a.out arg1 ... argn
работает точно так же, как
ocamlrun a.out arg1 ... argn
Обратите внимание, что нельзя передавать параметры команде ocamlrun при прямом вызове a.out.
Windows: В нескольких версиях Windows файлы исполняемого байткода являются самозапускаемыми только в том случае, если их имя оканчивается на .exe. Рекомендуется всегда использовать имена .exe для исполняемых файлов байткода, например, компилировать с ocamlc -o myprog.exe ..., а не ocamlc -o myprog ....
13.2 Параметры
Следующие параметры командной строки распознаются командой ocamlrun.
- -b
- При аварийном завершении программы из-за неперехваченного исключения, вывести подробный «стек вызовов» выполнения, показывающий, где было вызвано исключение и какие функции были активны в этот момент. Стек вызовов выводится только если исполняемый байткод содержит отладочную информацию, т.е. был скомпилирован и скомпонован с параметром -g для ocamlc. Это эквивалентно установке флага b в переменной среды OCAMLRUNPARAM (см. ниже).
- -config
- Вывести номер версии ocamlrun и подробное описание его конфигурации, а затем завершиться.
- -I dir
- Добавить каталог dir в список для поиска динамически загружаемых библиотек, помимо стандартного пути поиска (см. раздел 13.3).
- -m
- Вывести магическое число исполняемого байткода, заданного в качестве аргумента, и завершиться.
- -M
- Вывести магическое число, ожидаемое для файлов исполняемого байткода этой версией системы выполнения, и завершиться.
- -p
- Вывести имена примитивов, известных этой версии ocamlrun, и завершиться.
- -t
- Увеличивает уровень отслеживания для отладочной системы выполнения (в противном случае игнорируется).
- -v
- Направляет менеджер памяти на вывод некоторых сообщений о процессе на стандартный поток ошибок. Это эквивалентно установке v=61 в переменной среды OCAMLRUNPARAM (см. ниже).
- -version
- Вывести строку версии и завершиться.
- -vnum
- Вывести короткий номер версии и завершиться.
Также учитываются следующие переменные среды:
- CAML_LD_LIBRARY_PATH
- Дополнительные каталоги для поиска динамически загружаемых библиотек (см. раздел 13.3).
- OCAMLLIB
- Каталог, содержащий стандартную библиотеку OCaml. (Если OCAMLLIB не задан, используется CAMLLIB). Используется для поиска файла конфигурации ld.conf для динамической загрузки (см. раздел 13.3). Если не задан, используется каталог библиотеки, указанный при компиляции OCaml.
- OCAMLRUNPARAM
- Устанавливает параметры системного времени выполнения и параметры сборки мусора. (Если OCAMLRUNPARAM не задан, используется CAMLRUNPARAM). Эта переменная должна быть последовательностью спецификаций параметров, разделенных запятыми. Для удобства запятые в начале переменной игнорируются, а несколько запятых интерпретируются как одна. Спецификация параметра — это буква-опция, за которой следует знак =, десятичное число (или шестнадцатеричное число, начинающееся с 0x) и необязательный множитель. Опции описаны ниже; опции a, i, l, m, M, n, o, O, s, v, w соответствуют полям записи control, описанным в Модуле Gc.
- a
- (allocation_policy) Политика, используемая для выделения памяти в куче OCaml. Возможные значения: 0 для политики «следующее свободное место», 1 для политики «первое свободное место» и 2 для политики «лучшее свободное место». По умолчанию используется 2 (лучшее свободное место). Подробности см. в документации модуля Gc.
- b
- (обратный след) Выводит обратный след стека при аварийном завершении программы из-за необработанного исключения. Можно указать необязательный аргумент: b=0 — выключает вывод обратного следа; b=1 эквивалентно b и включает вывод обратного следа; b=2 включает вывод обратного следа и принудительно загружает отладочную информацию во время запуска программы, а не при выводе обратного следа. b=2 можно использовать, если система времени выполнения не может загрузить отладочную информацию при выводе обратного следа, например, если нет доступных дескрипторов файлов.
- c
- (cleanup_on_exit) Обеспечивает аккуратное завершение работы системы выполнения при выходе (см. caml_shutdown в разделе 20.7.5). Опция также включает пулинг (как в caml_startup_pooled). Этот режим может использоваться для обнаружения утечек с помощью стороннего отладчика памяти.
- h
- Начальный размер основной кучи (в словах).
- H
- Выделение блоков кучи с помощью mmap огромных страниц. Огромные страницы зафиксированы в памяти и не подлежат подкачке.
- i
- (major_heap_increment) Значение по умолчанию для приращения размера основной кучи. (в словах, если больше 1000, иначе в процентах от размера кучи)
- l
- (stack_limit) Предел размера стека (в словах). Это актуально только для интерпретатора байт-кода, поскольку интерпретатор нативного кода использует стек операционной системы.
- m
- (custom_minor_ratio) Ограничение на плавающую память для памяти вне кучи, удерживаемой пользовательскими значениями в малой куче. Минорный сбор мусора запускается, когда такое количество памяти удерживается пользовательскими значениями, расположенными в малой куче. Выражается в процентах от размера малой кучи. По умолчанию: 100. Примечание: это относится только к значениям, выделенным с помощью caml_alloc_custom_mem.
- M
- (custom_major_ratio) Целевое отношение плавающей памяти к размеру основной кучи для памяти вне кучи, удерживаемой пользовательскими значениями (например, bigarrays), расположенными в основной куче. Скорость сборки мусора настраивается так, чтобы использовать такое количество памяти для мертвых значений, которые ещё не собраны. Выражается в процентах от размера основной кучи. По умолчанию: 44. Примечание: это относится только к значениям, выделенным с помощью caml_alloc_custom_mem.
- n
- (custom_minor_max_size) Максимальное количество памяти вне кучи для каждого пользовательского значения, выделенного в малой куче. Когда пользовательское значение выделяется в малой куче и занимает более этого количества байтов, только это значение учитывается в отношении custom_minor_ratio, а остальное напрямую учитывается в отношении custom_major_ratio. По умолчанию: 8192 байта. Примечание: это относится только к значениям, выделенным с помощью caml_alloc_custom_mem.
- o
- (space_overhead) Настройка скорости основного сбора мусора. Подробности см. в документации модуля Gc.
- O
- (max_overhead) Настройка триггера уплотнения кучи.
- p
- (отладочный вывод синтаксического анализатора) Включает поддержку отладки для синтаксических анализаторов, сгенерированных ocamlyacc. При включении этой опции автоматический автомат, который выполняет синтаксический анализ, выводит трассировку своих действий.
- R
- (случайность) Включает случайную инициализацию всех таблиц хеширования по умолчанию (см. Модуль Hashtbl).
- s
- (minor_heap_size) Размер малой кучи. (в словах)
- t
- Устанавливает уровень трассировки для отладочного режима времени выполнения (игнорируется стандартным режимом времени выполнения).
- v
- (verbose) Какие сообщения сборщика мусора выводить в stderr. Это сумма значений, выбранных из следующего списка:
- 1 (= 0x001)
- Начало и конец цикла основного сбора мусора.
- 2 (= 0x002)
- Минорный сбор и фрагмент основного сбора мусора.
- 4 (= 0x004)
- Изменение размера кучи.
- 8 (= 0x008)
- Изменение размеров стеков и таблиц менеджера памяти.
- 16 (= 0x010)
- Уплотнение кучи.
- 32 (= 0x020)
- Изменение параметров сборки мусора.
- 64 (= 0x040)
- Вычисление размера фрагмента основного сбора мусора.
- 128 (= 0x080)
- Вызов функций завершения.
- 256 (= 0x100)
- Сообщения при запуске (загрузка файла байт-кода, разрешение общих библиотек).
- 512 (= 0x200)
- Вычисление условия срабатывания уплотнения.
- 1024 (= 0x400)
- Вывод статистики сборки мусора при выходе из программы.
- w
- (window_size) Установка размера окна, используемого основным сбором мусора для сглаживания колебаний рабочей нагрузки. Целое число от 1 до 50. (По умолчанию: 1)
- W
- Вывод предупреждений во время выполнения в stderr (например, канал, открытый на файле, умирает без закрытия, невыведенные данные и т. д.)
Если символ параметра не распознан, весь параметр игнорируется; если знак равенства или число отсутствуют, значение принимается как 1; если множитель не распознан, он игнорируется.
Например, на 32-битной машине под bash команда
export OCAMLRUNPARAM='b,s=256k,v=0x015'
указывает последующему ocamlrun на вывод трассировок для неперехваченных исключений, устанавливает начальный размер меньшей кучи в 1 мегабайт и выводит сообщение в начале каждого цикла сборки мусора, когда размер кучи изменяется, и когда запускается уплотнение.
- CAMLRUNPARAM
- Если OCAMLRUNPARAM не найден в среде, то будет использоваться CAMLRUNPARAM. Если также не найден CAMLRUNPARAM, будут использованы значения по умолчанию.
- PATH
- Список каталогов, в которых ищется исполняемый файл байткода.
13.3 Динамическая загрузка общих библиотек
На платформах, поддерживающих динамическую загрузку, ocamlrun может динамически связываться с C общими библиотеками (DLL), предоставляя дополнительные C-примитивы, помимо тех, которые предоставляет стандартная система выполнения. Имена этих библиотек предоставляются во время компоновки, как описано в разделе 20.1.4), и записываются в исполняемый файл байткода; ocamlrun затем находит эти библиотеки и разрешает ссылки на их примитивы при запуске программы байткода.
Команда ocamlrun ищет общие библиотеки в следующих каталогах в указанном порядке:
- Каталоги, указанные в командной строке ocamlrun с опцией -I.
- Каталоги, указанные в переменной окружения CAML_LD_LIBRARY_PATH.
- Каталоги, указанные во время компоновки с помощью опции -dllpath для ocamlc. (Эти каталоги записываются в исполняемый файл байткода.)
- Каталоги, указанные в файле ld.conf. Этот файл находится в каталоге стандартной библиотеки OCaml и содержит имена каталогов (по одному в строке), которые будут проверяться. Как правило, он содержит только одну строку с именем подкаталога stublibs каталога стандартной библиотеки OCaml. Пользователи могут добавить туда имена других каталогов, содержащих часто используемые общие библиотеки; однако для обеспечения согласованности установки рекомендуется устанавливать общие библиотеки непосредственно в системный каталог stublibs, а не добавлять строки в файл ld.conf.
- Каталоги, которые проверяются по умолчанию системным загрузчиком динамических библиотек. В Unix эти каталоги обычно включают /lib и /usr/lib, а также каталоги, перечисленные в файле /etc/ld.so.conf и переменной среды LD_LIBRARY_PATH. В Windows эти каталоги включают системные каталоги Windows, а также каталоги, указанные в переменной среды PATH.
13.4 Общие ошибки
В этом разделе описаны и объяснены наиболее часто встречающиеся сообщения об ошибках.
- filename: no such file or directory
- Если filename — имя исполняемого файла байткода, это означает, что либо файла не существует, либо при попытке запустить интерпретатор байткода ocamlrun в нём произошла ошибка. Второй вариант указывает на то, что OCaml не был правильно установлен на вашей системе.
- Cannot exec ocamlrun
- (При запуске исполняемого файла байткода.) Интерпретатор ocamlrun не был найден в пути к исполняемым файлам. Проверьте, правильно ли установлен OCaml на вашей системе.
- Cannot find the bytecode file
- Файл, который ocamlrun пытается выполнить (например, файл, указанный в качестве первого аргумента, не являющегося опцией, для ocamlrun), либо не существует, либо не является допустимым исполняемым файлом байткода.
- Truncated bytecode file
- Файл, который ocamlrun пытается выполнить, не является допустимым исполняемым файлом байткода. Вероятно, он был усечён или повреждён с момента создания. Удалите и перестройте его.
- Uncaught exception
- Выполняемая программа содержит «блуждающее» исключение. То есть, она поднимает исключение в какой-то момент, и это исключение никогда не перехватывается. Это приводит к немедленному завершению программы. Имя исключения печатается вместе со строкой, последовательностью байтов и целочисленными аргументами (аргументы более сложных типов не напечатаны корректно). Чтобы найти контекст неперехваченного исключения, скомпилируйте программу с опцией -g и либо запустите её снова в отладчике ocamldebug (см. главу 18), либо запустите её с ocamlrun -b или с переменной окружения OCAMLRUNPARAM, установленной в b=1.
- Out of memory
- Выполняемой программе требуется больше памяти, чем доступно. Либо программа строит чрезмерно большие структуры данных; либо программа содержит слишком много вложенных вызовов функций, и стек переполняется. В некоторых случаях ваша программа абсолютно правильна, просто ей требуется больше памяти, чем предоставляет ваша машина. В других случаях сообщение «недостаточно памяти» раскрывает ошибку в вашей программе: нетерминирующая рекурсивная функция, выделение чрезмерно большого массива, строки или последовательности байтов, попытки построить бесконечный список или другие структуры данных, …
Чтобы помочь вам диагностировать эту ошибку, запустите программу с опцией -v для ocamlrun или с переменной окружения OCAMLRUNPARAM, установленной в v=63. Если вы видите много сообщений «Growing stack…», это, вероятно, циклическая рекурсивная функция. Если вы видите много сообщений «Growing heap…», с медленным увеличением размера кучи, это, вероятно, попытка построить структуру данных с слишком большим количеством (бесконечным количеством?) ячеек. Если вы видите немного сообщений «Growing heap…», но с огромным увеличением размера кучи, это, вероятно, попытка построить чрезмерно большой массив, строку или последовательность байтов.
© 1995-2022 INRIA.
https://v2.ocaml.org/releases/4.14/htmlman/runtime.html