Печать обратной трассировки не работает

У меня есть следующий блок кода:

try
   raise Exit (* body *)
with
| e ->
  Printexc.record_backtrace true;
  printf "Unexpected exception : %s\n" (Printexc.to_string e);
  let x = Printexc.get_backtrace () in
  print_string x;
  Printexc.print_backtrace stdout

Код в body действительно вызывает исключение, и он показывает Unexpected exception : Pervasives.Exit, однако он не печатает никакой обратной трассировки.

Я компилирую файл с -g и export OCAMLRUNPARAM=b, кто-нибудь знает причину, по которой нельзя распечатать бэктрейс?


person SoftTimur    schedule 24.08.2013    source источник


Ответы (1)


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

Сегодня мне пришло в голову, что вероятная проблема заключается в том, что OCAMLRUNPARAM на самом деле не установлен в вашем процессе. Может быть сложно заставить переменные окружения передаваться через команды make(1). Одна из причин заключается в том, что каждая строка в Makefile выполняется отдельной оболочкой.

Еще одна вещь, влияющая на обратные трассировки, — это встраивание. Если ваши функции сложны, это, вероятно, не влияет на вас. Но вы можете отключить почти все встраивания с помощью -inline 0. Маловероятно, что это будет иметь значение между отсутствием трассировки стека и трассировкой стека. Это может иметь значение между более короткими и более длинными трассировками стека.

Вот эксперимент, в котором встраивание имеет значение:

$ cat m.ml
try
    let f () : int = raise Exit
    in let g () = f () + 2
    in let h () = g () + 3
    in let main () = Printf.printf "%d\n" (h () + 4)
    in main ()
with
    e -> Printf.printf "%s" (Printexc.get_backtrace ())
$ ocamlopt -inline 10 -g -o m m.ml
$ OCAMLRUNPARAM=b m
Raised by primitive operation at file "m.ml", line 3, characters 18-22
$ ocamlopt -inline 0 -g -o m m.ml
$ OCAMLRUNPARAM=b m
Raised at file "m.ml", line 2, characters 27-31
Called from file "m.ml", line 3, characters 18-22
Called from file "m.ml", line 4, characters 18-22
Called from file "m.ml", line 5, characters 43-47
Called from file "m.ml", line 6, characters 7-14
person Jeffrey Scofield    schedule 24.08.2013
comment
На самом деле, в месте body сложный код, а место, где возникает радикальное исключение, находится в каких-то других файлах, поэтому для печати должна быть трассировка стека... - person SoftTimur; 24.08.2013
comment
Хорошо, извините! Все, о чем я могу думать, это убедиться, что все скомпилировано с помощью -g. Такого провала, как вы описываете, я не видел. - person Jeffrey Scofield; 24.08.2013
comment
Я скопировал ваш код в свой main.ml и установил make-файл с -inline 0, -g и OCAMLRUNPARAM=b, создание файлов возвращает Fatal error: exception Pervasives.Exit make: *** [summary] Error 2, но не место, где возникает исключение. - person SoftTimur; 24.08.2013
comment
Это прогресс. Вы можете внимательно изучить вывод make, чтобы убедиться, что он выдает команды так, как вы ожидаете. Или вы можете попробовать провести мой эксперимент дословно. FWIW, моя среда — OS X 10.8.4, OCaml 4.00.1. - person Jeffrey Scofield; 24.08.2013
comment
Я провел ваш эксперимент дословно, он работает так, как вы показали... но я также не вижу ничего плохого в командах, сгенерированных моим makefile... - person SoftTimur; 25.08.2013
comment
Я пересмотрел свой эксперимент, чтобы он выглядел как ваш код и работал так же, как и раньше. Возможно проблема в деталях body. - person Jeffrey Scofield; 25.08.2013
comment
Убедитесь, что OCAMLRUNPARAM действительно правильно установлен в вашем процессе. - person Jeffrey Scofield; 26.08.2013