[erlang-questions] Logging from nif (and especially from rust nif)

Daniel Goertzen <>
Mon Sep 18 18:08:10 CEST 2017


The suggestion from https://github.com/rust-lang/rust/issues/24821 is to
use writeln! instead of println! so you can handle the WOULDBLOCK situation
yourself instead of panicing.  But, shooting all the messages over to the
Erlang side seems to solve your problem.

On Sun, Sep 17, 2017 at 2:28 PM Max Lapshin <> wrote:

>
> Hi.
>
> I'm playing now with rust nif and can advice nice library:
> https://github.com/hansihe/rustler
>
> For those of us, who do not understand what is there about elixir: don't
> worry, no need to use it, there should be a simple makefile for compiling
> rust.
>
>
> I've met stange situation while using println!  mechanism in rust nif
>  (I'm speaking about enterprise real world debugging: as lot of prints as
> possible).  Nif crashes from println.
>
> if you are lucky to catch debug message, you will see something like:
>
> stack backtrace:
>
>    0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
>
>    1: std::sys_common::backtrace::_print
>
>    2: std::panicking::default_hook::{{closure}}
>
>    3: std::panicking::default_hook
>
>    4: std::panicking::rust_panic_with_hook
>
>    5: std::panicking::begin_panic
>
>
> or even info about error code 35.
>
>
> Problem is that stdout is in non-blocking mode and when rust tries to
> write output, it gets error that it is not waiting for.
>
> I've decided not to change anything in rust stdlib, but use another
> mechanism:
>
> 1) take pid of output writing process
>
> 2) send messages to it from rust.
>
>
> Here is the way to get whom to send IO request messages:
>
> logger() ->
>
>   UserDrv = whereis(user_drv),
>
>   CurGroup = case (is_pid(UserDrv) andalso process_info(UserDrv,
> dictionary)) of
>
>     {dictionary, UserDrvDict} ->
>
>       proplists:get_value(current_group, UserDrvDict);
>
>     _ ->
>
>       undefined
>
>   end,
>
>   case is_pid(CurGroup) of
>
>     true ->
>
>       CurGroup;
>
>     false ->
>
>       {_,GL} = process_info(self(),group_leader),
>
>       GL
>
>   end.
>
>
> and here is how do I log there from rust:
>
>
>   if let Some(ref logger) = mpegts.logger {
>     env.pid();
>     env.send(logger, (
>       atoms::io_request().encode(env),
>       env.pid().encode(env),
>       atoms::ok().encode(env),
>       (
>         atoms::put_chars().encode(env),
>         atoms::unicode().encode(env),
>         (string+"\n").encode(env)
>       ).encode(env)
>     ).encode(env))
>   }
>
>
> One simple hack here: I do not send Mref as 3'rd argument, but I send atom
> ok. Seems to be working.
>
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170918/4a589bc0/attachment.html>


More information about the erlang-questions mailing list