diff -Nur audacious-3.6.2-orig/src/audacious/main.cc audacious-3.6.2/src/audacious/main.cc
--- audacious-3.6.2-orig/src/audacious/main.cc 2015-05-31 00:27:01.000000000 +0200
+++ audacious-3.6.2/src/audacious/main.cc 2015-11-22 12:24:15.858308588 +0100
@@ -49,6 +49,7 @@
int qt;
} options;
+static bool initted = false;
static Index<PlaylistAddItem> filenames;
static const struct {
@@ -300,6 +301,16 @@
static void main_cleanup (void)
{
+ if (initted)
+ {
+ /* Somebody was naughty and called exit() instead of aud_quit().
+ * aud_cleanup() has not been called yet, so there's no point in running
+ * leak checks. Note that it's not safe to call aud_cleanup() from the
+ * exit handler, since we don't know what context we're in (we could be
+ * deep inside the call tree of some plugin, for example). */
+ AUDWARN ("exit() called unexpectedly; skipping normal cleanup.\n");
+ return;
+ }
filenames.clear ();
aud_cleanup_paths ();
aud_leak_check ();
@@ -356,6 +367,7 @@
signals_init_two ();
#endif
+ initted = true;
aud_init ();
do_commands ();
@@ -379,6 +391,7 @@
#endif
aud_cleanup ();
+ initted = false;
return EXIT_SUCCESS;
}
diff -Nur audacious-3.6.2-orig/src/libaudcore/multihash.h audacious-3.6.2/src/libaudcore/multihash.h
--- audacious-3.6.2-orig/src/libaudcore/multihash.h 2015-05-31 00:27:01.000000000 +0200
+++ audacious-3.6.2/src/libaudcore/multihash.h 2015-11-22 12:22:45.550171540 +0100
@@ -54,9 +54,12 @@
size (0),
used (0) {}
- ~HashBase ()
- { delete[] buckets; }
-
+ void clear () // use as destructor
+ {
+ delete[] buckets;
+ * this = HashBase ();
+ }
+
int n_items () const
{ return used; }
@@ -112,6 +115,11 @@
locks (),
channels () {}
+ /* There is no destructor. In some instances, such as the string pool, it
+ * is never safe to destroy the hash table, since it can be referenced from
+ * the destructors of other static objects. It is left to the operating
+ * system to reclaim the memory used by the hash table upon process exit. */
+
/* All-purpose lookup function. The caller passes in the data to be looked
* up along with its hash value. The two callbacks are optional. <add> is
* called if no matching node is found, and may return a new node to add to
@@ -187,8 +195,11 @@
}
void clear ()
- { HashBase::iterate (remove_cb, nullptr); }
-
+ {
+ HashBase::iterate (remove_cb, nullptr);
+ HashBase::clear ();
+ }
+
private:
struct Node : public HashBase::Node
{