[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Gc.compact weirdness help



Yes, you need to be *very* careful about not getting the CAMLlocal/return
orders wrong, or your stack will become corrupted due to not registering
the appropriate local roots for the GC.  This sort of issue also does not
necessarily register a segfault as it will silently alter a few bytes of
your stack, depending on the liveness of the value.

The way to debug this is by switching your libasmrun.a (which is the OCaml
native code runtime and present in the OCaml standard library directory)
with libasmrund.a.  This is the asmrun compiled with -DDEBUG, and includes
aggressive heap-integrity checks that are triggered on every entry to the
major GC.  This checking, combined with frequent calls to Gc.compact in
your code, are sufficient to find these bugs much more easily.

You can compile a libasmrund.a from the OCaml distribution (cd asmrun &&
make libasmrund.a).  You have to manually swap the library with
OCaml-3.12, but the upcoming OCaml-4.00 has a compiler flag to switch to
the debug library without needing to go through this process.

-anil


On Wed, Jul 18, 2012 at 10:21:23PM -0700, Haris Rotsos wrote:
> So I found my problem on the aforthmentioned  problem, and I am writing
> here the solution just for the records.
> 
> reading a bit the documentation about c interfacing of ocaml, I discovered
> that then CAMLlocal1 function registers a value variable with the gc, but
> is not sufficient if the function is not returing with the CAMLReturn
> method. I think the problem is that the Gc during a compact face will try
> to change memory mapping and update also the value of the local variable.
> If this variable is in the stuck, then the gc will not be able to update
> its value. The strange thing is the code never returned a segfault.
> 
> In order to sort this problem I did the following modification in the c
> code:
> 
> On 17 July 2012 10:21, Haris Rotsos <cr409@xxxxxxxxxxxx> wrote:
> 
> > bool
> > PktDemux(Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t proto,
> >     const Address &src, const Address &dst, NetDevice::PacketType type) {
> > -  CAMLlocal1( ml_data );
> >
> +  value ml_data;
> +  caml_register_global_root(&ml_data);
> 
>   printf("packet demux...\n");
> >   fprintf(stdout, "%f: receiving %u packet done...\n",
> >       (long)Simulator::Now().GetMicroSeconds() / 1e6, pkt->GetSize());
> >   fflush(stdout);
> >
> >   int pkt_len = pkt->GetSize();
> >   ml_data = caml_alloc_string(pkt_len);
> >   pkt->CopyData((uint8_t *)String_val(ml_data), pkt_len);
> >
> >   // find host name
> >   string node_name = getHostName(dev);
> >
> >   //printf("node %s.%d packet\n", node_name.c_str(), dev->GetIfIndex());
> >   // call packet handling code in caml
> >   caml_callback3(*caml_named_value("demux_pkt"),
> >       caml_copy_string((const char *)node_name.c_str()),
> >       Val_int(dev->GetIfIndex()), ml_data );
> >   printf("packet demux end...\n");
> >
> 
> +  caml_remove_global_root(&ml_data);
> 
> 
> >   return true;
> > }
> >
> 
> pretty simple but pretty tricky also to know about it. I had to revert
> reading some source code from relevant project (basically it was a code
> binding of ocaml to a video codec library) in order to figure out the
> solution.
> 
> -- 
> Charalampos Rotsos
> PhD student
> The University of Cambridge
> Computer Laboratory
> William Gates Building
> JJ Thomson Avenue
> Cambridge
> CB3 0FD
> 
> Phone: +44-(0) 1223 767032
> Email: cr409@xxxxxxxxxxxx

-- 
Anil Madhavapeddy                                 http://anil.recoil.org



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.