ss3681755

ss3681755

NIFs raise Segmentation Fault while loading function has try catch block to handle the exception

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.

Most Liked

OvermindDL1

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).

OvermindDL1

OvermindDL1

Because Undefined Behavior allows for anything, and most of they time they screw with the optimizers in weird ways.

al2o3cr

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 catch section 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.

Where Next?

Popular in Questions Top

_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: &lt;h1&gt;Create Post&lt;/h1&gt; &lt;%= ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36128 110
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

We're in Beta

About us Mission Statement