Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: "Markus Weißmann" <markus.weissmann@in.tum.de>
To: <caml-list@inria.fr>
Cc: Gerd Stolpmann <info@gerd-stolpmann.de>,
	Mark Shinwell <mshinwell@janestreet.com>
Subject: Re: [Caml-list] Obj.out_of_heap_tag, out of minor heap or memory corruption?
Date: Fri, 29 Apr 2016 17:41:17 +0200	[thread overview]
Message-ID: <a2b256a93395b0237cb2288593e9cd84@in.tum.de> (raw)
In-Reply-To: <CAM3Ki75cZLYbhUaTVR0Zm9McJu4SHayuoQdcP51CiiC0XA7tnw@mail.gmail.com>

Thanks a lot Gerd and Mark: It was in the C code: A missing 
CAMLlocal(). =)

The funny thing was: It had _nothing_ to do with the piece of code the 
bug surfaced around.
So for anyone reading this thread in the future, tearing your hair out 
in frustration:
Check your C code.

I hereby confirm the Stolpmann-Theorem: "Its always the C code."

regards
Markus

On 2016-04-29 16:57, Mark Shinwell wrote:
> It may be worth printing the pointer at the time of allocation of 
> this
> record, and then at the time just before the assertion fails.  I 
> think
> you can just Obj.magic the record to "int" (use printf and %d) and
> then when you see the answer on the screen, multiply it by 2 to get
> the correct pointer.  Or send it back to a C binding and printf it
> from there.  Anyway, this might help to diagnose whether the value 
> was
> moved between the allocation and the failure; it seems likely it was.
> If so it's probably a missing CAMLlocal or similar.
>
> The thing about it being very sensitive to the heap size is
> characteristic of that kind of bug.  You're effectively relying on a
> particular allocation triggering a GC, so the heap has to be full at
> just the right time.
>
> Another technique that can be useful for diagnosing heap corruption 
> is
> gdb watchpoints on the part of the value concerned.
>
> Mark
>
> On 29 April 2016 at 15:14, Markus Weißmann 
> <markus.weissmann@in.tum.de> wrote:
>> On 2016-04-29 15:17, Gerd Stolpmann wrote:
>>>
>>> Am Freitag, den 29.04.2016, 13:04 +0200 schrieb Markus Weißmann:
>>>>
>>>> Hello,
>>>>
>>>> I have a server program that crashes after some time with a very
>>>> strange error:
>>>> The (=) comparison of two values returns false, even though they 
>>>> are
>>>> pretty identical.
>>>> They are of type { a : int; b : int } and the comparison always 
>>>> fails
>>>> on the second integer.
>>>> When printing the compared integers, they are always 0 (as 
>>>> expected) --
>>>> both of them; but are not equal (=).
>>>> I started inspecting the values with the "Obj.tag" and found them 
>>>> to be
>>>> always of type Obj.int_tag -- until the non-equalness strikes:
>>>> One of the compared integers then always has Obj.out_of_heap_tag. 
>>>> This
>>>> value surprisingly behaved like an integer unless compared to 
>>>> another:
>>>>
>>>> let (x : int) =
>>>>    print_int x; (* "0" *)
>>>>    assert (x = 0) (* fails! *)
>>>>
>>>> Can someone explain what this tag means exactly and if this
>>>> works-as-intended or if my heap must have gotten hit by some 
>>>> faulty C
>>>> bindings?
>>>
>>>
>>> Obj.tag is meaningless for ints.
>>>
>>> What could have happened is that a C lib did not set the LSB of the 
>>> word
>>> (which is required for ints in order to make them distinguishable 
>>> from
>>> pointers). The C lib MUST use Val_int or Val_long to create the 
>>> values
>>> (and these macros set the LSB).
>>>
>>> Check whether Obj.is_int returns true. If not, something is wrong.
>>>
>>
>> The value comes from C bindings, but from a string-value via 
>> Char.code.
>> It is then passed through a constructor-function to create the 
>> record;
>> I added a check there to see if the C bindings are to blame:
>>
>>   type foo = { a : int; b : int }
>>
>>   let create (a : int) (b : int) =
>>     assert (Obj.is_int (Obj.repr x)); (* always holds *)
>>     { a; b }
>>
>> This assertion never triggered so far.
>> I replaced the equality check by a function which now also asserts 
>> the
>> is_int property:
>>
>>   let equal (x : foo) (y : foo) = (* y is a static value living 
>> through the
>> entire run; x is from a parse/allocate/compare/throw-away cycle *)
>>     assert (Obj.is_int (Obj.repr x.a));
>>     assert (Obj.is_int (Obj.repr y.a));
>>     assert (Obj.is_int (Obj.repr x.b)); (* <- this fails after a 
>> while *)
>>     assert (Obj.is_int (Obj.repr y.b));
>>     x = y
>>
>> and one of these (always the same) triggers after a while (after 
>> some 10.000
>> calls).
>> But only with the standard minor heap size, not with a 4 MB sized 
>> one.
>> There are no other functions working on these values; they are 
>> parsed, put
>> through
>> the constructor function, compared and thrown away.
>>
>> Regards
>> Markus
>>
>> --
>> Markus Weißmann, M.Sc.
>> Technische Universität München
>> Institut für Informatik
>> Boltzmannstr. 3
>> D-85748 Garching
>> Germany
>> http://wwwknoll.in.tum.de/
>>
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa.inria.fr/sympa/arc/caml-list
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs

-- 
Markus Weißmann, M.Sc.
Technische Universität München
Institut für Informatik
Boltzmannstr. 3
D-85748 Garching
Germany
http://wwwknoll.in.tum.de/

  reply	other threads:[~2016-04-29 15:41 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-29 11:04 Markus Weißmann
2016-04-29 13:17 ` Gerd Stolpmann
2016-04-29 14:14   ` Markus Weißmann
2016-04-29 14:25     ` Gerd Stolpmann
2016-05-02  8:27       ` Sébastien Hinderer
2016-05-02 14:30         ` Gabriel Scherer
2016-05-03 15:59           ` Boris Yakobowski
2016-04-29 14:57     ` Mark Shinwell
2016-04-29 15:41       ` Markus Weißmann [this message]
2016-04-29 16:41         ` Adrien Nader

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a2b256a93395b0237cb2288593e9cd84@in.tum.de \
    --to=markus.weissmann@in.tum.de \
    --cc=caml-list@inria.fr \
    --cc=info@gerd-stolpmann.de \
    --cc=mshinwell@janestreet.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox