Avoid on-exit crashes when adaptation is enabled.

After trunk r13269 (Vector refactor) destroyed vector objects still have
positive item counts. This exposes use-after-delete bugs. In this particular
case, global adaptation rule/group/service arrays are destructed by global
destruction sequence first and then again by Adaptation::*::TheConfig objects
destructors.

This change avoiding static destruction order dependencies by storing those
global adaptation arrays on heap.

=== modified file 'src/adaptation/AccessRule.cc'
--- src/adaptation/AccessRule.cc	2013-05-13 22:48:23 +0000
+++ src/adaptation/AccessRule.cc	2014-02-20 01:27:36 +0000
@@ -34,42 +34,42 @@ Adaptation::AccessRule::finalize()
             g->finalize(); // explicit groups were finalized before rules
             AllGroups().push_back(g);
         }
     }
 
     if (!group()) {
         debugs(93, DBG_CRITICAL, "ERROR: Unknown adaptation service or group name: '" <<
                groupId << "'"); // TODO: fail on failures
     }
 }
 
 Adaptation::ServiceGroupPointer
 Adaptation::AccessRule::group()
 {
     return FindGroup(groupId);
 }
 
 Adaptation::AccessRules &
 Adaptation::AllRules()
 {
-    static AccessRules TheRules;
-    return TheRules;
+    static AccessRules *TheRules = new AccessRules;
+    return *TheRules;
 }
 
 // TODO: make AccessRules::find work
 Adaptation::AccessRule *
 Adaptation::FindRule(const AccessRule::Id &id)
 {
     typedef AccessRules::iterator ARI;
     for (ARI i = AllRules().begin(); i != AllRules().end(); ++i) {
         if ((*i)->id == id)
             return *i;
     }
 
     return NULL;
 }
 
 Adaptation::AccessRule *
 Adaptation::FindRuleByGroupId(const String &groupId)
 {
     typedef AccessRules::iterator ARI;
     for (ARI i = AllRules().begin(); i != AllRules().end(); ++i) {

=== modified file 'src/adaptation/Service.cc'
--- src/adaptation/Service.cc	2014-02-04 19:47:14 +0000
+++ src/adaptation/Service.cc	2014-02-20 01:28:25 +0000
@@ -37,42 +37,42 @@ Adaptation::Service::wants(const Service
 
     // sending a message to a broken service is likely to cause errors
     if (cfg().bypass && broken())
         return false;
 
     if (up()) {
         // Sending a message to a service that does not want it is useless.
         // note that we cannot check wantsUrl for service that is not "up"
         // note that even essential services are skipped on unwanted URLs!
         return wantsUrl(filter.request->urlpath);
     }
 
     // The service is down and is either not bypassable or not probed due
     // to the bypass && broken() test above. Thus, we want to use it!
     return true;
 }
 
 Adaptation::Services &
 Adaptation::AllServices()
 {
-    static Services TheServices;
-    return TheServices;
+    static Services *TheServices = new Services;
+    return *TheServices;
 }
 
 Adaptation::ServicePointer
 Adaptation::FindService(const Service::Id& key)
 {
     typedef Services::iterator SI;
     for (SI i = AllServices().begin(); i != AllServices().end(); ++i) {
         if ((*i)->cfg().key == key)
             return *i;
     }
     return NULL;
 }
 
 void Adaptation::DetachServices()
 {
     while (!AllServices().empty()) {
         AllServices().back()->detach();
         AllServices().pop_back();
     }
 }

=== modified file 'src/adaptation/ServiceGroups.cc'
--- src/adaptation/ServiceGroups.cc	2014-02-02 09:42:23 +0000
+++ src/adaptation/ServiceGroups.cc	2014-02-20 01:26:45 +0000
@@ -298,35 +298,35 @@ Adaptation::ServicePlan::next(const Serv
     if (!atEof && !group->findLink(filter, ++pos))
         atEof = true;
     return current();
 }
 
 std::ostream &
 Adaptation::ServicePlan::print(std::ostream &os) const
 {
     if (!group)
         return os << "[nil]";
 
     return os << group->id << '[' << pos << ".." << group->services.size() <<
            (atEof ? ".]" : "]");
 }
 
 /* globals */
 
 Adaptation::Groups &
 Adaptation::AllGroups()
 {
-    static Groups TheGroups;
-    return TheGroups;
+    static Groups *TheGroups = new Groups;
+    return *TheGroups;
 }
 
 Adaptation::ServiceGroupPointer
 Adaptation::FindGroup(const ServiceGroup::Id &id)
 {
     typedef Groups::iterator GI;
     for (GI i = AllGroups().begin(); i != AllGroups().end(); ++i) {
         if ((*i)->id == id)
             return *i;
     }
 
     return NULL;
 }


