From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by sympa.inria.fr (Postfix) with ESMTPS id 8D66E7ED39 for ; Mon, 16 Jul 2012 17:06:05 +0200 (CEST) Received-SPF: None (mail1-smtp-roc.national.inria.fr: no sender authenticity information available from domain of mrchebas@gmail.com) identity=pra; client-ip=74.125.83.54; receiver=mail1-smtp-roc.national.inria.fr; envelope-from="mrchebas@gmail.com"; x-sender="mrchebas@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail1-smtp-roc.national.inria.fr: domain of mrchebas@gmail.com designates 74.125.83.54 as permitted sender) identity=mailfrom; client-ip=74.125.83.54; receiver=mail1-smtp-roc.national.inria.fr; envelope-from="mrchebas@gmail.com"; x-sender="mrchebas@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail1-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-ee0-f54.google.com) identity=helo; client-ip=74.125.83.54; receiver=mail1-smtp-roc.national.inria.fr; envelope-from="mrchebas@gmail.com"; x-sender="postmaster@mail-ee0-f54.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Am8BACctBFBKfVM2kGdsb2JhbABFuS8IIgEBAQEJCQ0HFAQjgiABAQEDARICLAEbHgMBCwYFCzsCHwEBEQEFARwGEyKHWwEDBgadcgkDjCOCcYRhChknDVeIcQEFDIpOZhWGMgOOTYEhhU2LBIMlPoQAgVU X-IronPort-AV: E=Sophos;i="4.77,594,1336341600"; d="ml'?scan'208";a="167038897" Received: from mail-ee0-f54.google.com ([74.125.83.54]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 16 Jul 2012 17:06:05 +0200 Received: by eekb47 with SMTP id b47so294239eek.27 for ; Mon, 16 Jul 2012 08:06:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=vwHJ3WPS6RFmNuWbXEmQ4n9yp3UuzP5fCCSSzq/HDGg=; b=Yv/wMCgROuDhxUW9wI6LtNJuP5z6frm6am/jjAggNDB2uQYGXtq4YES86sN2Ys2B+5 d52XqLXQeQbAimCvIXZUmC68yFAgeUGzBca0rhF3ELaGspP82TkMC4qZpkacQ64kNouJ SOJSpVSVPuIUr1hdGrbMV1G3UKur50y3LCm+lSZKz3PqIs7vy1hSl2f8UDbmsxljxsf1 /Xmd55XDSJg8F+gnRLxrTDOTZyuUGmmQhdYbSKjZJ68/qZD2zMmEVWz4BxUG2RNLZra1 vvPx6mxHbmb/BWoAWFFNLI/BGD1P7HnejHjMHV6PGs7auE3tdCIQZxqWij/sgq/oJLww MgEQ== MIME-Version: 1.0 Received: by 10.152.144.99 with SMTP id sl3mr11675128lab.44.1342451164697; Mon, 16 Jul 2012 08:06:04 -0700 (PDT) Received: by 10.112.82.41 with HTTP; Mon, 16 Jul 2012 08:06:04 -0700 (PDT) In-Reply-To: References: Date: Mon, 16 Jul 2012 17:06:04 +0200 Message-ID: From: Alexey Rodriguez To: OCaml List Content-Type: multipart/mixed; boundary=e89a8f2346ffccd51004c4f3c428 Subject: [Caml-list] Re: Exception backtraces and stack overflows --e89a8f2346ffccd51004c4f3c428 Content-Type: multipart/alternative; boundary=e89a8f2346ffccd50704c4f3c426 --e89a8f2346ffccd50704c4f3c426 Content-Type: text/plain; charset=ISO-8859-1 Hi again, A colleague suggested doing the following experiment: call List.map on a large list and throw an exception from deep down in the call chain. Now the backtrace I get contains 1022 entries for map, an entry for the raise site and some other entry. This matches the 1024 limit of BACKTRACE_BUFFER_SIZE. Since the limit has been reached, the backtrace is useless to diagnose the stack overflow. This matches my understanding of caml_stash_backtrace: all stack frames are inspected and reported as long as there is space in the trace buffer. So it seems there is something funny happening when a stack overflow is detected in the SIGSEGV handler: there are only 3 trace entries whereas the stack contains over a hundred thousand frames. Is this intended behavior? If it is of any help I am including the test program. I am using Ocaml 3.12.0 on a x86-64 platform. Cheers, Alexey On Mon, Jul 16, 2012 at 3:51 PM, Alexey Rodriguez wrote: > Hi, > > I am having trouble understanding exception backtraces for stack overflows. > > Sometimes the backtrace only contains entries for the function that filled > the stack with frames (you would see many backtrace entries pointing to > List.map if you were trying to map a very long list). Such traces are > useless to fix the stack overflow since you cannot use them to find the > code path that leads to List.map. > > In other situations, the backtrace contains the full path from the Ocaml > entry point to the recursive functions that is blowing up the stack. In > these situations the backtrace appears to have "compressed" the hundreds of > thousands of frames that the recursive calls generated since there is only > one entry for List.map. > > Is there documentation that explains when you get one backtrace or the > other? I tried to understand the source code of caml_stash_backtrace and > there it seems that all the stack frames are captured (if the backtrace > buffer size allows). Casual inspection with gdb shows that > caml_stash_backtrace does not get the full stack at the moment of the > fault. Maybe the signal handler is skipping over the hundreds of thousands > of frames somehow? If someone can elucidate this mystery for me I'll be > very grateful! > > I can provide more details if needed, but probably someone on the list can > already help with this short description. > > Oh, one more question on backtraces. I see that when tracing is enabled, > caml_stash_backtrace is called whenever an exception is thrown. This might > be expensive as Not_found is raised by many functions in the standard > library. Is there a high overhead in leaving tracing enabled? This is > useful in production systems as very often it is not possible to have the > original inputs to trigger the bug in a debug build. > > Thanks! > > Alexey > --e89a8f2346ffccd50704c4f3c426 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Hi again,

A colleague suggested doing the following expe= riment: call List.map on a large list and throw an exception from deep down= in the call chain.

Now the backtrace I get contai= ns 1022 entries for map, an entry for the raise site and some other entry. = This matches the 1024 limit of BACKTRACE_BUFFER_SIZE. Since the limit has b= een reached, the backtrace is useless to diagnose the stack overflow. This = matches my understanding of caml_stash_backtrace: all stack frames are insp= ected and reported as long as there is space in the trace buffer.

So it seems there is something funny happening when a s= tack overflow is detected in the SIGSEGV handler: =A0there are only 3 trace= entries whereas the stack contains over a hundred thousand frames. Is this= intended behavior?

If it is of any help I am including the test program. I= am using Ocaml 3.12.0 on a x86-64 platform.

Cheer= s,

Alexey

On Mon, Jul 16, 2012 at 3:51 PM, Alexey Rodriguez <mrchebas@gmail.com= > wrote:
Hi,

I am having trouble understanding exception backtrac= es for stack overflows.

Sometimes the backtrace on= ly contains entries for the function that filled the stack with frames (you= would see many backtrace entries pointing to List.map if you were trying t= o map a very long list). Such traces are useless to fix the stack overflow = since you cannot use them to find the code path that leads to List.map.

In other situations, the backtrace contains the full pa= th from the Ocaml entry point to the recursive functions that is blowing up= the stack. In these situations the backtrace appears to have "compres= sed" the hundreds of thousands of frames that the recursive calls gene= rated since there is only one entry for List.map.

Is there documentation that explains when you get one b= acktrace or the other? I tried to understand the source code of caml_stash_= backtrace and there it seems that all the stack frames are captured (if the= backtrace buffer size allows). Casual inspection with gdb shows that caml_= stash_backtrace does not get the full stack at the moment of the fault. May= be the signal handler is skipping over the hundreds of thousands of frames = somehow? If someone can=A0elucidate=A0this mystery for me I'll be very = grateful!

I can provide more details if needed, but probably some= one on the list can already help with this short description.
Oh, one more question on backtraces. I see that when tracing is= enabled, caml_stash_backtrace is called whenever an exception is thrown. T= his might be expensive as Not_found is raised by many functions in the stan= dard library. Is there a high overhead in leaving tracing enabled? This is = useful in production systems as very often it is not possible to have the o= riginal inputs to trigger the bug in a debug build.

Thanks!

Alexey

--e89a8f2346ffccd50704c4f3c426-- --e89a8f2346ffccd51004c4f3c428 Content-Type: application/octet-stream; name="stack_overflow.ml" Content-Disposition: attachment; filename="stack_overflow.ml" Content-Transfer-Encoding: base64 X-Attachment-Id: f_h4porara0 CmxldCBtYWtlX2xpc3QgbiA9CiAgbGV0IHJlYyBnbyBhY2N1bSA9IGZ1bmN0 aW9uCiAgICB8IDAgLT4gYWNjdW0KICAgIHwgbiAtPiBnbyAobjo6YWNjdW0p IChuLTEpCiAgaW4KICBnbyBbXSBuCgpsZXQgcmVjIG15X21hcCBmID0gZnVu Y3Rpb24KICB8IFtdIC0+IFtdCiAgfCAoeDo6eHMpIC0+CiAgICAgIGxldCB5 ID0gZiB4IGluCiAgICAgIGxldCB5cyA9IG15X21hcCBmIHhzIGluCiAgICAg IHkgOjogeXMKCmV4Y2VwdGlvbiBEaWVfZGllX2RpZQoKKCogTWFrZSB0aGlz IGZhbHNlIHRvIGdlbmVyYXRlIGEgIm5vcm1hbGx5IGhhbmRsZWQiIGV4Y2Vw dGlvbiBhbmQgZ2V0CiAqIG1hbnkgYmFja3RyYWNlIGVudHJpZXMuICopCmxl dCBnZW5lcmF0ZV9zdGFja19vdmVyZmxvdyA9IHRydWUKCmxldCBpbmMgbiA9 CiAgaWYgbm90IGdlbmVyYXRlX3N0YWNrX292ZXJmbG93ICYmIG4gPSAxMDAw MCB0aGVuIHJhaXNlIERpZV9kaWVfZGllOwogIG4gKyAxCgpsZXQgbWFpbiAo KSA9CiAgUHJpbnRmLmZwcmludGYgc3RkZXJyICJNYWtpbmcgbGlzdFxuIjsK ICBsZXQgbCA9IG1ha2VfbGlzdCAoMTAwMCAqIDQwMCkgaW4KICBQcmludGYu ZnByaW50ZiBzdGRlcnIgIk1hcHBpbmdcbiI7CiAgbGV0IF9sMiA9IG15X21h cCBpbmMgbCBpbgogIFByaW50Zi5mcHJpbnRmIHN0ZGVyciAiRG9uZVxuIgoK bGV0ICgpID0gbWFpbiAoKQoK --e89a8f2346ffccd51004c4f3c428--