[erlang-questions] open_port returns enoent even when driver init function executes correctly.

Patrik Nyblom <>
Mon Jan 7 18:53:02 CET 2013


Hi!

You do not need to file a bug, I saw the error in the doc a few weeks 
ago and corrected it in master. It will be correct in R16.
The port_driver.c code looks like this in master:
---------------------
/* port_driver.c */

#include <stdio.h>
#include "erl_driver.h"

typedef struct {
     ErlDrvPort port;
} example_data;

static ErlDrvData example_drv_start(ErlDrvPort port, char *buff)
{
     example_data* d = (example_data*)driver_alloc(sizeof(example_data));
     d->port = port;
     return (ErlDrvData)d;
}

static void example_drv_stop(ErlDrvData handle)
{
     driver_free((char*)handle);
}

static void example_drv_output(ErlDrvData handle, char *buff,
                    ErlDrvSizeT bufflen)
{
     example_data* d = (example_data*)handle;
     char fn = buff[0], arg = buff[1], res;
     if (fn == 1) {
       res = foo(arg);
     } else if (fn == 2) {
       res = bar(arg);
     }
     driver_output(d->port, &res, 1);
}

ErlDrvEntry example_driver_entry = {
     NULL,            /* F_PTR init, called when driver is loaded */
     example_drv_start,        /* L_PTR start, called when port is opened */
     example_drv_stop,        /* F_PTR stop, called when port is closed */
     example_drv_output,        /* F_PTR output, called when erlang has 
sent */
     NULL,            /* F_PTR ready_input, called when input descriptor 
ready */
     NULL,            /* F_PTR ready_output, called when output 
descriptor ready */
     "example_drv",        /* char *driver_name, the argument to 
open_port */
     NULL,            /* F_PTR finish, called when unloaded */
     NULL,                       /* void *handle, Reserved by VM */
     NULL,            /* F_PTR control, port_command callback */
     NULL,            /* F_PTR timeout, reserved */
     NULL,            /* F_PTR outputv, reserved */
     NULL,                       /* F_PTR ready_async, only for async 
drivers */
     NULL,                       /* F_PTR flush, called when port is about
                    to be closed, but there is data in driver
                    queue */
     NULL,                       /* F_PTR call, much like control, sync call
                    to driver */
     NULL,                       /* F_PTR event, called when an event 
selected
                    by driver_event() occurs. */
     ERL_DRV_EXTENDED_MARKER,    /* int extended marker, Should always be
                    set to indicate driver versioning */
     ERL_DRV_EXTENDED_MAJOR_VERSION, /* int major_version, should always be
                        set to this value */
     ERL_DRV_EXTENDED_MINOR_VERSION, /* int minor_version, should always be
                        set to this value */
     0,                          /* int driver_flags, see documentation */
     NULL,                       /* void *handle2, reserved for VM use */
     NULL,                       /* F_PTR process_exit, called when a
                    monitored process dies */
     NULL                        /* F_PTR stop_select, called to close an
                    event object */
};

DRIVER_INIT(example_drv) /* must match name in driver_entry */
{
     return &example_driver_entry;
}
-------------------------------

Cheers,
/Patrik
On 01/04/2013 04:18 AM, Jeffrey Rennie wrote:
>
> Here's the first real clue.  The  example driver is being unloaded 
> before it's invoked!  See below for the call stack of the unload.
>
> This must be either a bug in the documentation at
>
> http://www.erlang.org/doc/tutorial/c_portdriver.html
>
> or a bug in the erlang itself.
>
> What's the process for filing a bug?
>
> 0439f644 517572e2 example_drv!example_drv_finish(void)+0x1e 
> [c:\users\jeff\code\code\port_driver\port_driver.cpp @ 64]
>
> 0439f654 51757729 beam_smp!do_unload_driver_entry(struct DE_Handle * 
> dh = 0x00000000, unsigned long * save_name = 0x00000000)+0x72 
> [c:\users\jeff\github\otp\erts\emulator\beam\erl_bif_ddll.c @ 1655]
>
> 0439f680 51797c2b beam_smp!ddll_no_more_references(void * vdh = 
> 0x517576d0)+0x59 
> [c:\users\jeff\github\otp\erts\emulator\beam\erl_bif_ddll.c @ 1221]
>
> 0439f69c 5179b89f beam_smp!exec_misc_ops(struct ErtsRunQueue_ * rq = 
> 0x518c3b8c)+0x7b 
> [c:\users\jeff\github\otp\erts\emulator\beam\erl_process.c @ 7231]
>
> 0439f6c8 51801be7 beam_smp!schedule(struct process * p = 0x00000002, 
> int calls = 0)+0x5df 
> [c:\users\jeff\github\otp\erts\emulator\beam\erl_process.c @ 6891]
>
> 0439f6fc 7714c7c5 beam_smp!process_main+0x167
>
> *From:*Robert Raschke [mailto:]
> *Sent:* Thursday, January 03, 2013 12:37 AM
> *To:* SurferJeff
> *Cc:* ; 
> *Subject:* Re: [erlang-questions] open_port returns enoent even when 
> driver init function executes correctly.
>
> You can try running erl.exe with sasl enabled to get better error 
> messages.
>
> The messages you see at the moment are coming out interleaved, like in 
> the old joke "When faced with a problem you decide to use threading, 
> ..."  :-)
>
> Robby
>
> On Jan 3, 2013 4:53 AM, "SurferJeff" < 
> <mailto:>> wrote:
>
> I found the recipe to build debug:
>
> $ cd $ERL_TOP
> $ rm bin/win32/erlexec.dll
> $ cd erts/emulator
> $ make debug
> $ cd ../etc
> $ make debug
>
> And it succeeded.  However, the next command in the recipe fails:
>
>  <mailto:>/cygdrive/c/Users/jeff/GitHub/otp
> $ make local_setup
> make[1]: Entering directory `/cygdrive/c/Users/jeff/GitHub/otp/erts'
> make[2]: Entering directory 
> `/cygdrive/c/Users/jeff/GitHub/otp/erts/start_script
> s'
> make[2]: Nothing to be done for `debug'.
> make[2]: Leaving directory 
> `/cygdrive/c/Users/jeff/GitHub/otp/erts/start_scripts
> '
> ct_run.exe dialyzer.exe erl.ini erl_crash.dump escript.exe 
> run_test.exe typer.ex
> e werl.exe win32
> make[2]: Entering directory 
> `/cygdrive/c/Users/jeff/GitHub/otp/erts/start_script
> s'
> /usr/bin/install -c -d 
> /cygdrive/c/users/jeff/github/otp/erts/start_scripts/tmp
> ( cd /cygdrive/c/users/jeff/github/otp/erts/start_scripts/tmp && \
>   erlc -W -I/cygdrive/c/users/jeff/github/otp/lib/kernel/ebin 
> -I/cygdrive/c/use
> rs/jeff/github/otp/lib/stdlib/ebin 
> -I/cygdrive/c/users/jeff/github/otp/lib/sasl/
> ebin +no_warn_sasl +otp_build -o 
> /cygdrive/c/users/jeff/github/otp/bin/start.scr
> ipt /cygdrive/c/users/jeff/github/otp/erts/start_scripts/start_clean.rel )
> File not found: 
> "c:/cygdrive/c/users/jeff/github/otp/erts/start_scripts/start_cl
> ean.rel"
> Makefile:129: recipe for target 
> `/cygdrive/c/users/jeff/github/otp/bin/start.scr
> ipt' failed
> make[2]: *** [/cygdrive/c/users/jeff/github/otp/bin/start.script] Error 1
> make[2]: Leaving directory 
> `/cygdrive/c/Users/jeff/GitHub/otp/erts/start_scripts
> '
> Makefile:69: recipe for target `local_setup' failed
> make[1]: *** [local_setup] Error 2
> make[1]: Leaving directory `/cygdrive/c/Users/jeff/GitHub/otp/erts'
> Makefile:883: recipe for target `local_setup' failed
> make: *** [local_setup] Error 2
>
> And now my erl.exe is completely hosed:
>
>  
> <mailto:>/cygdrive/c/Users/jeff/GitHub/otp/bin/win32
> $ ./erl.exe
> {(no error logger present"i)n ietr rtoerr: m"iEnrartoirn gi ni np 
> rdooc_ebsoost
> "<,0{.b2a.d0a>r wgi,t[h{ eerxli_tp rviaml_uleo:a 
> d{ebra,dcahregc,k[_{feirlle__pr
> reismu_llto,a3d,e[r{,fcihleec,k"_efrill_ep_rriems_ullota,d3er,[.{efrill"e},,\{"l
> eirnle_,p28r3i}m]_}l,o{aidneirt.,egrelt\_"b}o,o{tl,i1n,e[,{2f8i3l}e,]"}i,n{iitn.
> ite,rgle"t},_{bloionte,,178,5[}{]f}i,l{ei,n\i"ti,ngiett._ebrolo\t",}2,,{[l{ifnie
> l,e7,8"5i}n]i}t,.{eirnli"t},,g{elti_nbeo,o77t2,}2]},,[{{ifniilte,,d\o"_ibnoiott.
> ,e3r,l[\{"f}i,l{el,i"nien,i7t7.2e}r]l}",}{,i{nliitn,ed,o73_9b}o]o}t],}3},
> [{file,\"init.erl\"},{line,739}]}]}\n"
>
> Crash dump was written to: erl_crash.dump
> init terminating in do_boot ()
>
>
> On Wednesday, January 2, 2013 7:26:09 PM UTC-8, SurferJeff wrote:
>
>     I'm working through the example here:
>     http://www.erlang.org/doc/tutorial/c_portdriver.html
>     And I'm trying to get it to run on Windows.  I reordered the code
>     in the C
>     source so that it compiles, and added a module.def file so that
>     erlang
>     actually finds and executes the driver init function.
>
>     I attached a debugger.  Walking back up the stack, I observe that:
>     The driver init function returns correctly.
>     erts_sys_ddll_call_init() returns correctly.
>     do_load_driver_entry() returns ERL_DE_NO_ERROR.
>     load_driver_entry() returns ERL_DE_NO_ERROR.
>     erl_ddll_try_load_3 returns t = TUPLE2(hp, am_ok, ok_term); on
>     line 417 of
>     erl_bif_ddl.c.
>     But the next higher call on the stack is _process_main(), which
>     was compiled
>     with gcc and has no debug symbols so I can't step through and
>     figure out why
>     the end result is:
>
>     =ERROR REPORT==== 2-Jan-2013::19:14:22 ===
>     Error in process <0.31.0> with exit value:
>     {enoent,[{erlang,open_port,[{spawn,"example_drv"},[]],[]},{complex5,init,1,[
>
>     {file,"c:/Users/jeff/code/code/port_driver/complex5.erl"},{line,19}]}]}
>
>
>     Has anyone seen this before?
>
>     If not, how do I recompile erl.exe purely with cl.exe (no gcc) so
>     that it
>     generates debug symbols?  And while I'm recompiling, how do I turn
>     off all
>     optimizations?  I can read basic make files, but I get lost in the
>     configure
>     scripts and .in and .mk files.  Please take pity on a Windows
>     programmer ;-)
>
>
>     _______________________________________________
>     erlang-questions mailing list
>      <mailto:>
>     http://erlang.org/mailman/listinfo/erlang-questions
>
>
> _______________________________________________
> erlang-questions mailing list
>  <mailto:>
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
>
> _______________________________________________
> 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/20130107/5f0beb92/attachment.html>


More information about the erlang-questions mailing list