ss3681755
I am working on integrating a C++ api with Elixir, by using NIFs. Now whenever I load the NIF, I want to initialize some variables/data which will be persisted across NIF calls. I was trying to achieve the same by load function mentioned in the ERL_NIF_INIT call. But I am observing some weird behavior out of load function. Please have a look at the below mentioned example and then I’ll explain the issue further:
#include <erl_nif.h>
static ERL_NIF_TERM sample(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
return enif_make_atom(env, "ok");
}
static ErlNifFunc nif_funcs[] = {{"sample", 1, sample}};
static int load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) {
try {
1 / 0; // nif loads if this is the case
int x = 1 / 0; // float point exception segmentation fault when used this line
} catch (...) {
return 1;
}
return 0;
}
ERL_NIF_INIT(Elixir.Sample, nif_funcs, load, NULL, NULL, NULL);
Now closely observe the load function containing the try/catch block, when I use 1 / 0; expression in the body of try block, NIF is loaded but when the expression 1 / 0; is replaced by int x = 1 / 0; erlang vm fails to load NIF and crashes with floating point exception segmentation fault even if I have added the try/catch block to handle the exception. Can someone explain this to me? I really need help here.
Here is the elixir code used for interfacing:
defmodule Sample do
@on_load :load_nifs
def load_nifs do
:ok =
:sample
|> :code.priv_dir()
|> Path.join("sample")
|> :erlang.load_nif("0.0.1")
end
def sample(_) do
raise "sample/1 Function not implemented"
end
end
Command used to compile NIF g++ -fPIC -shared sample.cpp -o sample.so
P.S. - Thanks for your time to read this, I really appreciate it.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 3- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
OvermindDL1
C++ does not have an exception for a divide by zero, rather that is Undefined Behaviour, meaning the C++ compiler is allowed to do whatever it wants from give you back invalid data to crashing to wiping your entire system, everything is allowed, and a try/catch cannot stop it. This is why untrusted input to division should always be checked for zero first in C/C++.
EDIT: If you’re curious the spec defines it as UB in section 5.6.4 of the C++ standard (at least in the version I have here).
al2o3cr
The word “exception” in that message refers to a hardware exception, not the C++ kind.
In fact, modern compilers don’t generate any code at all for the
catchsection in your example because they can determine it will never execute:Note that if you switch to the
1 / 0;version, the compiler omits the division entirely because it sees the result is completely unused. TBH I’m not sure why assigning the value to a local variable (that immediately goes out-of-scope) doesn’t do this too.OvermindDL1
Because Undefined Behavior allows for anything, and most of they time they screw with the optimizers in weird ways.