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/
next prev parent 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