albertz / music-player

Music player - endlessly plays your music
http://albertz.github.io/music-player/
BSD 2-Clause "Simplified" License
492 stars 59 forks source link

crash in sqlite3_initialize #22

Closed albertz closed 11 years ago

albertz commented 11 years ago

This was reported by @christheswiss:

Crashed Thread:  0

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000108

VM Regions Near 0x108:
-->
    __TEXT                 0000000100000000-0000000100004000 [   16K] r-x/rwx SM=COW  /Applications/MusicPlayer.app/Contents/MacOS/MusicPlayer

Application Specific Information:
objc[2008]: garbage collection is OFF
*** multi-threaded process forked ***

Thread 0 Crashed:
0   libsystem_kernel.dylib         0x00007fff8d76d82a __kill + 10
1   libsystem_c.dylib              0x00007fff9409ccfa _sigtramp + 26
2   libdispatch.dylib              0x00007fff928dca8d _dispatch_barrier_async_f_slow + 62
3   libsqlite3.dylib               0x00007fff8dbd3f52 sqlite3_initialize + 2018
4   libsqlite3.dylib               0x00007fff8dbd2a77 openDatabase + 71
5   _sqlite3.so                    0x00000001072518b8 pysqlite_connection_init + 308
6   org.python.python              0x0000000100052262 0x100009000 + 299618
7   org.python.python              0x00000001000104c0 PyObject_Call + 97
8   _sqlite3.so                    0x0000000107255d19 0x107250000 + 23833
9   org.python.python              0x000000010008aee1 PyEval_EvalFrameEx + 12787
10  org.python.python              0x000000010008dec3 0x100009000 + 544451

The related Python backtrace:

Current thread 0x0000000108b01000:
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 93 in test
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 69 in __init__
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 164 in <lambda>
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 201 in initDb
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 207 in decorated
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/Song.py", line 253 in id
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/utils.py", line 281 in __get__
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 789 in indexSearchDir
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 792 in indexSearchDir
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 792 in indexSearchDir
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 792 in indexSearchDir
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 792 in indexSearchDir
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 792 in indexSearchDir
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/songdb.py", line 800 in <lambda>
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/utils.py", line 830 in doCall
  File "/Applications/MusicPlayer.app/Contents/Resources/Python/utils.py", line 776 in _asyncCall

A very related crash: https://github.com/celery/celery/issues/869

albertz commented 11 years ago

I searched a bit around and here is probably the explanation:

  SQLite does not allow the use of database connections across `forked
  <http://en.wikipedia.org/wiki/Fork_(operating_system)>`__ processes
  (see the `SQLite FAQ Q6 <https://sqlite.org/faq.html#q6>`__).
  (Forking creates a child process that is a duplicate of the parent
  including the state of all data structures in the program.  If you
  do this to SQLite then parent and child would both consider
  themselves owners of open databases and silently corrupt each
  other's work and interfere with each other's locks.)

  One example of how you may end up using fork is if you use the
  `multiprocessing module
  <http://docs.python.org/library/multiprocessing.html>`__ which uses
  fork to make child processes.

  If you do use fork or multiprocessing on a platform that supports
  fork then you **must** ensure database connections and their objects
  (cursors, backup, blobs etc) are not used in the parent process, or
  are all closed before calling fork or starting a `Process
  <http://docs.python.org/library/multiprocessing.html#process-and-exceptions>`__.
  (Note you must call close to ensure the underlying SQLite objects
  are closed.  It is also a good idea to call `gc.collect(2)
  <http://docs.python.org/library/gc.html#gc.collect>`__ to ensure
  anything you may have missed is also deallocated.)
albertz commented 11 years ago

I hope this is fixed. The main code so far was the music indexing process - and this is a full fork+exec now, so they don't share any resources. This is all in https://github.com/albertz/music-player/compare/1907bc4295...000793be69.

All these changes might have introduced other crashes. I encountered some while testing. Not sure if they are still they. But they seem unrelated anyway - so this can be closed.