How to use the dynamic checker for detecting naked pointers?

$ opam switch create 4.10.0+nnpcheck

<><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
[ocaml-variants.4.10.0+nnpcheck] synchronised from git+https://github.com/kayceesrk/ocaml.git#4.10.0+nnp+check

<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
[ERROR] The compilation of ocaml-variants failed at "/mnt/sda5/_opam/opam-init/hooks/sandbox.sh build ./configure --prefix=/mnt/sda5/_opam/4.10.0+nnpcheck --enable-frame-pointers".
∗ installed base-bigarray.base
∗ installed base-threads.base
∗ installed base-unix.base

#=== ERROR while compiling ocaml-variants.4.10.0+nnpcheck =====================#
# context     2.0.6 | linux/x86_32 |  | https://opam.ocaml.org#e23e2627
# path        /mnt/sda5/_opam/4.10.0+nnpcheck/.opam-switch/build/ocaml-variants.4.10.0+nnpcheck
# command     /mnt/sda5/_opam/opam-init/hooks/sandbox.sh build ./configure --prefix=/mnt/sda5/_opam/4.10.0+nnpcheck --enable-frame-pointers
# exit-code   1
# env-file    /mnt/sda5/_opam/log/ocaml-variants-7731-2dea01.env
# output-file /mnt/sda5/_opam/log/ocaml-variants-7731-2dea01.out
### output ###
# [...]
# checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE
# checking whether more special flags are required for pthreads... no
# checking for PTHREAD_PRIO_INHERIT... yes
# configure: the POSIX threads library is supported
# checking for sigwait... yes
# checking bfd.h usability... no
# checking bfd.h presence... no
# checking for bfd.h... no
# configure: BFD library not found, 'ocamlobjinfo' will be unable to display info on .cmxs files.
# checking whether the assembler supports --debug-prefix-map... yes
# checking whether the assembler supports CFI directives... yes
# configure: error: frame pointers not supported on this platform



<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
┌─ The following actions failed
│ λ build ocaml-variants 4.10.0+nnpcheck
└─ 
┌─ The following changes have been performed (the rest was aborted)
│ ∗ install base-bigarray base
│ ∗ install base-threads  base
│ ∗ install base-unix     base
└─ 
# Run eval $(opam env) to update the current shell environment
Switch initialisation failed: clean up? ('n' will leave the switch partially installed) [Y/n] y

Which architecture are you trying to use this on? Currently the nnp checker only works on x64 architecture (as it uses a bit of assembly code that would need to be ported to other architectures).

Cheers,
Nicolás

OK, my computer is a 32bit indeed.
What is the recommended method to check naked pointers on 32bit computers?

Ah yes, I had missed that from the initial log. This is a wild guess, but I would try just removing the --enable-frame-pointers that is used during configuration (am not sure what is the right OPAM incantation for this). There is a chance it may work on x86 without any other change.

Cc @kayceesrk who will know the details.

Best wishes,
Nicolás

Unfortunately, the naked pointer checker does not build on 32-bit currently. See CI failure: https://travis-ci.org/github/kayceesrk/ocaml/jobs/724395486. @fccm Can you not compile your application on a 64-bit machine?

Should we add an availability flag To the package in opam that limits the package only to the compatible architectures? In which case, is it just x86-64?

My computer is a 32-bit machine. I don’t have another one.
I wrote several bindings, probably all, or maybe most of them use naked pointers (because I like to make something simple), I don’t know if I should update them all.

The manual now provides two ways to wrap pointers, a block with abstract tag and wrapped in a nativeint. Which method would you recommend? (the nativeint method seems more simple)

Does the “currently” mean that it will maybe be the case in the future?

There is also an even simpler way which is simply to tag pointers as ints (by “or-ing” with 1). This assumes that pointers are always 2-aligned (which is usually the case). This also avoids the allocation of the box around the pointer, which may be important in some situations.

The three methods are more or less equivalent in my view in the kind of guarantees that you get, but the way you interact with them from C is slightly different in each case.

There is yet another way which is to use a Custom_tag block instead of Abstract_tag. This allows you to define custom hashing/comparison for your type.

Cheers,
Nicolás

When isn’t it the case?

I don’t have a specific case in mind, but on the other hand am not sure there isn’t some exotic malloc implementation out there that returns non-aligned pointers.

Best wishes,
Nicolás

Pointers into e.g. char arrays, or to fields of packed structs, etc. need not be 2-aligned.