Inline_tests failing with SEGV

i am writing various unit tests for my program using ppx_expect. when i auto-promote my test file, if i have >1 test, it fails with

3 | (inline_tests)
Command got signal SEGV.

If there is only 1 test in the file, it runs fine.

I have had no luck troubleshooting this so i thought i’d ask here. Does anyone know where the SEGV comes from in inline_tests?

Any feedback/comments are appreciated :slight_smile:

I’m assuming you’re using dune to run everything ? In that case, in your _build directory there is a log file, where the commands are listed that dune executes. You can rerun those commands and see if you can get the same error; that’ll eliminate dune, and then, could you report back on the precise command that fails ? That might give some indication of where to look ? Also, maybe the problem is in dune (though I kinda doubt it).

The command causing the segfault is

cd _build/.sandbox/6c4a75786292b913625bc99e3ab2bb48/default/test/unit_tests && .unit_tests.inline-tests/inline_test_runner_unit_tests.exe inline-test-runner unit_tests -source-tree-root …/… -diff-cmd -

In which it is producing
[1] 81193 segmentation fault .unit_tests.inline-tests/inline_test_runner_unit_tests.exe inline-test-runner

in the .unit_tests.inline-tests directory, two files exist:

The .ml-gen file has the following contents
let () = Ppx_inline_test_lib.Runtime.exit ();;

not too sure where to look from here.


To be honest, I don’t actually know: I don’t use dune, and don’t use PPX-based infrastructure (I maintain and use Camlp5). But from here, I would next figure out how the inline_test_runner_unit_tests.exe and `inline-test-runner`` get built, and:

  1. if they’re built with the OPT compiler, switch them to BYTEcode
  2. maybe there are debug switches to turn on ?

Sorry, like I said, I don’t use that infrastructure, so I don’t know much about it. The only things I know about inline tests are what I learned by reverse-engineering them so I could write Camlp5-based equivalents.

This isn’t very helpful: I’m sorry. In recompense: recently I learned about mdx, and that’s some pretty slick stuff. I’ve started writing expect-based tests using MDX, and pretty (heh) “expect” to use that for all my expect-based testing in the future. It’s pretty slick stuff.

what version of dune are you using, and on which system (linux, mac, which kind of mac) ?

i am using Dune version 3.7.0 and am on Mac M1

2 likely culprits would be code signing, and some kind of race condition in the promotion process.

  • Can you post the output of codesign --verify --verbose inline_test_runner_unit_tests.exe ? (from the correct directory of course)
  • Can you try with an older dune (say, 3.2.0), with 3.7.1, and with the current main? (opam pin add dune --dev-repo ; opam pin remove dune to undo)

The output of running codesign --verify --verbose inline_test_runner_unit_tests.exe is
inline_test_runner_unit_tests.exe: valid on disk
inline_test_runner_unit_tests.exe: satisfies its Designated Requirement

Trying with Dune 3.2.0 also produced the same SEGV error too.

I have another test file in the same directory as well which is working as expected, which is why i am especially confused on why this particular file is causing inline_test to fail.

Another question: are you using the global dune cache? (cache enabled in the dune configuration or DUNE_CACHE variable set).

Also, one thing is that it’s perfectly possible that the test code you’re running is causing a segfault to happen (if you’re calling into buggy C code, something that uses Obj, an unsafe_ function, etc. Can you reproduce that with a short test program that uses no such code?

how can i find if i am using the global dune cache?

If inline_test is working for other test files, would that mean that the test file that causes the SEGV contains buggy code? Or are these things unrelated?

how can i find if i am using the global dune cache?

You can see this by looking at the top of _build/log, if “Shared cache: disabled” you’re not using it.

would that mean that the test file that causes the SEGV contains buggy code? Or are these things unrelated?

ppx_expect creates a program that calls the code that’s in let%expect_test blocks in your library code. This is the program that is segfaulting. To determine which part is a problem, you can remove or comment all the blocks one by one until you find the block that is the issue.
Then, the error can be in any of the functions that is called by that block.

One debugging trick you can use once you have identified the problematic block, is to extract it to a “normal” executable that links against your library. That puts ppx_expect out of the equation.