<p dir="ltr">Should the documentation mention this at the ffi level as well as in the Inside manual?</p>
<p dir="ltr">Sam</p>
<div class="gmail_quote">On Nov 2, 2013 12:49 AM, "Matthew Flatt" <<a href="mailto:mflatt@cs.utah.edu">mflatt@cs.utah.edu</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I tracked down the problem in the SQLite binding and Racket's GC.<br>
<br>
It turns out that an "interior" pointer retains an enclosing allocated<br>
object only when the pointer refers to an even address. A pointer that<br>
refers to an odd address is always treated by the GC as a fixnum (and<br>
it's not practical to change the GC to support odd-valued pointers into<br>
an allocated object). I've changed the documentation of<br>
scheme_malloc_allow_interior() to explain the constraint.<br>
<br>
Meanwhile, statement preparation in the SQLite API can return an<br>
odd-valued pointer into the middle of a query string (which had been<br>
allocated as 'atomic-interior). If a GC occurred at just the wrong<br>
time, then statement preparation could go wrong --- more so on Windows<br>
than other platforms, since the GC releases pages more eagerly on<br>
Windows. I've adjusted the SQLite binding to work within the newly<br>
documented constraint on interior pointers.<br>
<br>
I didn't find any other code that could end up with odd-valued<br>
pointers, but FFI users beware.<br>
<br>
At Wed, 30 Oct 2013 13:47:19 -0400, Ryan Culpepper wrote:<br>
> I don't have an answer about the crash, but Matthew has narrowed it down<br>
> to the vicinity of statement preparation, so I can make a recommendation<br>
> about how to avoid it: Use a (constant) parameterized statement instead<br>
> of string-append. For example, replace the main function with this:<br>
><br>
> (define (main n)<br>
>    (call-with-transaction<br>
>     (current-db)<br>
>     (lambda ()<br>
>       (for ([i (expt 10 n)])<br>
>         (define x_i (x i))<br>
>         (query-exec<br>
>          (current-db)<br>
>          "INSERT INTO sines (id, x, sine_x) VALUES (?,?,?)"<br>
>          i x_i (sin x_i))))))<br>
><br>
> With that change, I'm able to run (main 6) in about 30 seconds and (main<br>
> 7) in about 5 minutes on a 2GB, 1 processor Windows VM running within Linux.<br>
><br>
> The db connection caches prepared statements inside of transactions, so<br>
> by using a constant parameterized statement, you save parsing time. By<br>
> my measurements, this version takes less than half the time of<br>
> Matthias's. (In addition to other benefits like security from SQL<br>
> injection.)<br>
><br>
> Ryan<br>
><br>
><br>
> On 10/29/2013 06:19 PM, Andrews, Kyle (KC) wrote:<br>
> > I just tried running your code 3 times on `(main 7)' and twice on `(main 6)'<br>
> and it has crashed each time. But I was worried that somehow I was running out<br>
> of memory (even though I have 16 Gb available), so  I saved the database to<br>
> file using:<br>
> ><br>
> > (define current-db (make-parameter (sqlite3-connect #:database "buggy.db"<br>
> #:mode 'create)))<br>
> ><br>
> > [Note that if you want to run the script again after this, you have to<br>
> comment out the next line and remove the #:mode 'create keyword]<br>
> ><br>
> > DrRacket still crashes with (main 6) and (main 7).  Since (main 7) should<br>
> create a table with 10^7 = 10 million rows and 3 columns, I don't see how<br>
> SQLite could be running out of space.  SQLite documentation [1] says it should<br>
> be able to support at least 10^13 rows and 140 terabytes of data.  Otherwise,<br>
> I'm not sure what other limits I could be running into.  And my actual problem<br>
> is also using an on-disk database, for which I have managed to store a paltry<br>
> 47 mb (which is something like 1/300 of what I need to load).<br>
> ><br>
> > [1] <a href="http://www.sqlite.org/limits.html" target="_blank">http://www.sqlite.org/limits.html</a><br>
> ><br>
> > P.S. -- Happy Birthday!  (I saw the Easter egg in DrRacket today)<br>
> ><br>
> > -----Original Message-----<br>
> > From: Matthias Felleisen [mailto:<a href="mailto:matthias@ccs.neu.edu">matthias@ccs.neu.edu</a>]<br>
> > Sent: Tuesday, October 29, 2013 4:51 PM<br>
> > To: Andrews, Kyle (KC)<br>
> > Cc: Racket mailing list (<a href="mailto:users@racket-lang.org">users@racket-lang.org</a>)<br>
> > Subject: Re: [racket] frequent crashes on Windows 7 64-bit<br>
> ><br>
> ><br>
> > Once I had fixed the typo in your program, I was able to run this loop<br>
> without ado:<br>
> ><br>
> >> (for ((i (in-range 9))) (collect-garbage) (collect-garbage) (time<br>
> >> (main i)))<br>
> > cpu time: 1 real time: 1 gc time: 0<br>
> > cpu time: 5 real time: 6 gc time: 0<br>
> > cpu time: 9 real time: 9 gc time: 0<br>
> > cpu time: 77 real time: 77 gc time: 0<br>
> > cpu time: 736 real time: 741 gc time: 14 cpu time: 7666 real time: 7703 gc<br>
> time: 393 ...<br>
> ><br>
> > As far as I can tell time consumption grows by one order of magnitude as<br>
> increase the size of the database entries by an order of magnitude. I don't<br>
> have the time to it for 10, 11, and 12 but is it possible that something<br>
> external/size-wise hits you here?<br>
> ><br>
> ><br>
> ><br>
> > #lang racket<br>
> ><br>
> > (require db)<br>
> ><br>
> > (define current-db (make-parameter (sqlite3-connect #:database 'memory)))<br>
> ><br>
> > (query-exec (current-db) "CREATE TABLE sines(id INTEGER, x, sine_x)")<br>
> ><br>
> > (define (x i) (+ (- pi) (/ i (* 1000 pi))))<br>
> ><br>
> > (define (main n)<br>
> >    (call-with-transaction<br>
> >     (current-db)<br>
> >     (lambda ()<br>
> >       (for ([i (expt 10 n)])<br>
> >         (define x_i (x i))<br>
> >         (query-exec<br>
> >          (current-db)<br>
> >          (string-append<br>
> >           "INSERT INTO sines(id, x, sine_x) VALUES("<br>
> >           (number->string i) ", "<br>
> >           (number->string x_i) ", "<br>
> >           (number->string (sin x_i)) ")"))))))<br>
> ><br>
> > (provide main)<br>
> ><br>
> ><br>
> ><br>
> > On Oct 29, 2013, at 4:32 PM, "Andrews, Kyle (KC)" <<a href="mailto:KCAndrews@dow.com">KCAndrews@dow.com</a>> wrote:<br>
> ><br>
> >> I've been trying to upload data into an SQLite database using Racket from<br>
> Windows 7 64-bit and both Racket.exe and DrRacket.exe keep crashing before the<br>
> upload finishes.  I've had crashes on long-running programs in DrRacket on<br>
> Windows 7 before, so I don't want to say for sure that it's the fault of the<br>
> db library.  However, I do know is that the crashes have been happening<br>
> repeatedly with this project and given the amount of data I need to upload, it<br>
> is impractical to keep restarting Racket in the hopes that it will eventually<br>
> finish.  Racket is crashing with both 5.3.6 as well as the latest nightly<br>
> build you have installers for:   5.90.0.9.  I have attached a sample script<br>
> which creates an in-memory sqlite database and populates it with a trillion<br>
> sines which crashes on me after a while, just like my actual script.  My<br>
> Racket VM (at least in DrRacket) defaults to 2048 Mb.<br>
> >><br>
> >> Below is what error information Windows gives upon the crash:<br>
> >><br>
> >> Problem signature:<br>
> >>    Problem Event Name: APPCRASH<br>
> >>    Application Name:        Racket.exe<br>
> >>    Application Version:    5.90.0.1<br>
> >>    Application Timestamp:             525e4550<br>
> >>    Fault Module Name:    libracket3m_9r9qx5.dll<br>
> >>    Fault Module Version:                0.0.0.0<br>
> >>    Fault Module Timestamp:         525e454e<br>
> >>    Exception Code:             c0000005<br>
> >>    Exception Offset:          00000000002b6081<br>
> >>    OS Version:      6.1.7601.2.1.0.256.4<br>
> >>    Locale ID:          1033<br>
> >>    Additional Information 1:          9e37<br>
> >>    Additional Information 2:          9e37a01f62fc211801609d8b20878795<br>
> >>    Additional Information 3:          4bbb<br>
> >>    Additional Information 4:          4bbb32ba4ab4514f5750e1fc710f6223<br>
> >><br>
> >> Let me know if there is any other information I can provide.<br>
> >> Regards,<br>
> >><br>
> >> Kyle<br>
> >><br>
> >> <bug.rkt>____________________<br>
> >>   Racket Users list:<br>
> >>   <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
> ><br>
> ><br>
> ><br>
> ><br>
> > ____________________<br>
> >    Racket Users list:<br>
> >    <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
> ><br>
><br>
> ____________________<br>
>   Racket Users list:<br>
>   <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
____________________<br>
  Racket Users list:<br>
  <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
</blockquote></div>