shill: Move destruction of DBusControl object to AtExitManager

Some singleton objects (eg. DHCPProvider) accesses DBus in their
destructors which are called by AtExitManager.  We need to move the
destruction of the DBusControl object to AtExitManager as well to ensure
that it is destroyed after the singletons.

BUG=chromium-os:22389
TEST=Unit tests, manually cause shill to exit to ensure no crash

Change-Id: I2df27ff3c109457713be1a994b70a904c5f2d0f6
Reviewed-on: https://gerrit.chromium.org/gerrit/11067
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Tested-by: Thieu Le <thieule@chromium.org>
Commit-Ready: Thieu Le <thieule@chromium.org>
diff --git a/shill_main.cc b/shill_main.cc
index 5837947..2213466 100644
--- a/shill_main.cc
+++ b/shill_main.cc
@@ -70,6 +70,13 @@
   chromeos::InitLog(log_flags);
 }
 
+void DeleteDBusControl(void* param) {
+  VLOG(2) << __func__;
+  shill::DBusControl* dbus_control =
+      reinterpret_cast<shill::DBusControl*>(param);
+  delete dbus_control;
+}
+
 
 int main(int argc, char** argv) {
   base::AtExitManager exit_manager;
@@ -105,10 +112,13 @@
     config.UseFlimflamStorageDirs();
 
   // TODO(pstew): This should be chosen based on config
-  scoped_ptr<shill::DBusControl> dbus_control(new shill::DBusControl());
+  // Make sure we delete the DBusControl object AFTER the LazyInstances
+  // since some LazyInstances destructors rely on D-Bus being around.
+  shill::DBusControl* dbus_control = new shill::DBusControl();
+  exit_manager.RegisterCallback(DeleteDBusControl, dbus_control);
   dbus_control->Init();
 
-  shill::Daemon daemon(&config, dbus_control.get());
+  shill::Daemon daemon(&config, dbus_control);
 
   if (cl->HasSwitch(switches::kDeviceBlackList)) {
     vector<string> device_list;