BIND 10 trac2980, updated. 04e36988a16fb36ab84ec548a174b148924ed0d7 [2980] Final set of changes resulting from the first review

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Jul 4 11:25:19 UTC 2013


The branch, trac2980 has been updated
       via  04e36988a16fb36ab84ec548a174b148924ed0d7 (commit)
       via  b61e894db16aa458c9d3d405210c357e1fdde657 (commit)
       via  dc342c8d7ff4eff388bc596e625e54ac9617c09c (commit)
       via  57a25a015e23dca348c1e1a3c5821d64981277b1 (commit)
      from  d63e340ac318b68e1a04458ba9669f159d6eb508 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 04e36988a16fb36ab84ec548a174b148924ed0d7
Author: Stephen Morris <stephen at isc.org>
Date:   Thu Jul 4 12:24:47 2013 +0100

    [2980] Final set of changes resulting from the first review

commit b61e894db16aa458c9d3d405210c357e1fdde657
Author: Stephen Morris <stephen at isc.org>
Date:   Wed Jul 3 20:13:39 2013 +0100

    [2980] Various changes as a result of review

commit dc342c8d7ff4eff388bc596e625e54ac9617c09c
Author: Stephen Morris <stephen at isc.org>
Date:   Wed Jul 3 13:58:54 2013 +0100

    [2980] Updated as a result of the second part of the review.

commit 57a25a015e23dca348c1e1a3c5821d64981277b1
Author: Stephen Morris <stephen at isc.org>
Date:   Tue Jul 2 13:41:26 2013 +0100

    [2980] Changes as a result for the first part of the review

-----------------------------------------------------------------------

Summary of changes:
 src/lib/hooks/callout_handle.cc                    |   12 +-
 src/lib/hooks/callout_handle.h                     |   16 +-
 src/lib/hooks/callout_manager.cc                   |   16 +-
 src/lib/hooks/callout_manager.h                    |   11 +-
 src/lib/hooks/hooks.h                              |   16 +-
 src/lib/hooks/hooks_component_developer.dox        |  332 ++++++++++++--------
 src/lib/hooks/hooks_messages.mes                   |   62 ++--
 src/lib/hooks/library_manager.cc                   |  229 ++++++++------
 src/lib/hooks/library_manager.h                    |   16 +-
 src/lib/hooks/server_hooks.cc                      |    9 +-
 src/lib/hooks/server_hooks.h                       |    2 +-
 src/lib/hooks/tests/Makefile.am                    |   13 +-
 src/lib/hooks/tests/basic_callout_library.cc       |   12 +-
 src/lib/hooks/tests/callout_handle_unittest.cc     |    2 +-
 src/lib/hooks/tests/callout_manager_unittest.cc    |   28 +-
 src/lib/hooks/tests/common_test_class.h            |   58 ++--
 ...t_library.cc => framework_exception_library.cc} |   18 +-
 src/lib/hooks/tests/full_callout_library.cc        |   14 +-
 src/lib/hooks/tests/handles_unittest.cc            |   22 +-
 src/lib/hooks/tests/hooks_manager_unittest.cc      |   36 +--
 .../tests/library_manager_collection_unittest.cc   |    4 +-
 src/lib/hooks/tests/library_manager_unittest.cc    |  101 ++++--
 src/lib/hooks/tests/load_callout_library.cc        |   20 +-
 src/lib/hooks/tests/test_libraries.h.in            |    7 +-
 24 files changed, 625 insertions(+), 431 deletions(-)
 copy src/lib/hooks/tests/{load_error_callout_library.cc => framework_exception_library.cc} (77%)

-----------------------------------------------------------------------
diff --git a/src/lib/hooks/callout_handle.cc b/src/lib/hooks/callout_handle.cc
index 60d4a1d..ce9ef82 100644
--- a/src/lib/hooks/callout_handle.cc
+++ b/src/lib/hooks/callout_handle.cc
@@ -52,12 +52,12 @@ CalloutHandle::~CalloutHandle() {
     context_collection_.clear();
 
     // Normal destruction of the remaining variables will include the
-    // destruction of lm_collection_, wn action that will decrement the
-    // reference count on the library manager collection (which holds the
-    // libraries that could have allocated memory in the argument and context
-    // members).  When that goes to zero, the libraries will be unloaded:
-    // at that point nothing in the hooks framework will be pointing to memory
-    // in the libraries' address space.
+    // destruction of lm_collection_, an action that decrements the reference
+    // count on the library manager collection (which holds the libraries that
+    // could have allocated memory in the argument and context members.)  When
+    // that goes to zero, the libraries will be unloaded: at that point nothing
+    // in the hooks framework will be pointing to memory in the libraries'
+    // address space.
     //
     // It is possible that some other data structure in the server (the program
     // using the hooks library) still references the address space and attempts
diff --git a/src/lib/hooks/callout_handle.h b/src/lib/hooks/callout_handle.h
index 36a90f8..eb57fd4 100644
--- a/src/lib/hooks/callout_handle.h
+++ b/src/lib/hooks/callout_handle.h
@@ -80,11 +80,11 @@ class LibraryManagerCollection;
 ///   "context_destroy" callout.  The information is accessed through the
 ///   {get,set}Context() methods.
 ///
-/// - Per-library handle.  Allows the callout to dynamically register and
-///   deregister callouts. (In the latter case, only functions registered by
-///   functions in the same library as the callout doing the deregistration
-///   can be removed: callouts registered by other libraries cannot be
-///   modified.)
+/// - Per-library handle (LibraryHandle). The library handle allows the
+///   callout to dynamically register and deregister callouts. In the latter
+///   case, only functions registered by functions in the same library as the
+///   callout doing the deregistration can be removed: callouts registered by
+///   other libraries cannot be modified.
 
 class CalloutHandle {
 public:
@@ -168,7 +168,7 @@ public:
 
         value = boost::any_cast<T>(element_ptr->second);
     }
-    
+
     /// @brief Get argument names
     ///
     /// Returns a vector holding the names of arguments in the argument
@@ -273,7 +273,7 @@ public:
 
         value = boost::any_cast<T>(element_ptr->second);
     }
-    
+
     /// @brief Get context names
     ///
     /// Returns a vector holding the names of items in the context associated
@@ -355,7 +355,7 @@ private:
     const ElementCollection& getContextForLibrary() const;
 
     // Member variables
-    
+
     /// Pointer to the collection of libraries for which this handle has been
     /// created.
     boost::shared_ptr<LibraryManagerCollection> lm_collection_;
diff --git a/src/lib/hooks/callout_manager.cc b/src/lib/hooks/callout_manager.cc
index c67cfb0..0b75b1b 100644
--- a/src/lib/hooks/callout_manager.cc
+++ b/src/lib/hooks/callout_manager.cc
@@ -38,11 +38,11 @@ CalloutManager::checkLibraryIndex(int library_index) const {
     if (((library_index >= -1) && (library_index <= num_libraries_)) ||
         (library_index == INT_MAX)) {
         return;
-    } else {
-        isc_throw(NoSuchLibrary, "library index " << library_index <<
-                  " is not valid for the number of loaded libraries (" <<
-                  num_libraries_ << ")");
     }
+
+    isc_throw(NoSuchLibrary, "library index " << library_index <<
+              " is not valid for the number of loaded libraries (" <<
+              num_libraries_ << ")");
 }
 
 // Set the number of libraries handled by the CalloutManager.
@@ -62,7 +62,7 @@ CalloutManager::setNumLibraries(int num_libraries) {
 void
 CalloutManager::registerCallout(const std::string& name, CalloutPtr callout) {
     // Note the registration.
-    LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_REGISTER_CALLOUT)
+    LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_CALLOUT_REGISTRATION)
         .arg(current_library_).arg(name);
 
     // Sanity check that the current library index is set to a valid value.
@@ -142,7 +142,7 @@ CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) {
                 int status = (*i->second)(callout_handle);
                 if (status == 0) {
                     LOG_DEBUG(hooks_logger, HOOKS_DBG_EXTENDED_CALLS,
-                              HOOKS_CALLOUT).arg(current_library_)
+                              HOOKS_CALLOUT_CALLED).arg(current_library_)
                         .arg(ServerHooks::getServerHooks()
                             .getName(current_hook_))
                         .arg(reinterpret_cast<void*>(i->second));
@@ -209,7 +209,7 @@ CalloutManager::deregisterCallout(const std::string& name, CalloutPtr callout) {
     bool removed = initial_size != hook_vector_[hook_index].size();
     if (removed) {
         LOG_DEBUG(hooks_logger, HOOKS_DBG_EXTENDED_CALLS,
-                  HOOKS_DEREGISTER_CALLOUT).arg(current_library_).arg(name);
+                  HOOKS_CALLOUT_DEREGISTERED).arg(current_library_).arg(name);
     }
 
     return (removed);
@@ -244,7 +244,7 @@ CalloutManager::deregisterAllCallouts(const std::string& name) {
     bool removed = initial_size != hook_vector_[hook_index].size();
     if (removed) {
         LOG_DEBUG(hooks_logger, HOOKS_DBG_EXTENDED_CALLS,
-                  HOOKS_DEREGISTER_ALL_CALLOUTS).arg(current_library_)
+                  HOOKS_ALL_CALLOUTS_DEREGISTERED).arg(current_library_)
                                                 .arg(name);
     }
 
diff --git a/src/lib/hooks/callout_manager.h b/src/lib/hooks/callout_manager.h
index a9a5e31..4619006 100644
--- a/src/lib/hooks/callout_manager.h
+++ b/src/lib/hooks/callout_manager.h
@@ -41,7 +41,8 @@ public:
 /// @brief Callout Manager
 ///
 /// This class manages the registration, deregistration and execution of the
-/// library callouts.
+/// library callouts.  It is part of the hooks framework used by the BIND 10
+/// server, and is not for use by user-written code in a hooks library.
 ///
 /// In operation, the class needs to know two items of data:
 ///
@@ -59,7 +60,7 @@ public:
 ///   deregister callouts in the same library (including themselves): they
 ///   cannot affect callouts registered by another library.  When calling a
 ///   callout, the callout manager maintains the idea of a "current library
-///   index": if the callout calls one of the callout registration functions 
+///   index": if the callout calls one of the callout registration functions
 ///   (indirectly via the @ref LibraryHandle object), the registration
 ///   functions use the "current library index" in their processing.
 ///
@@ -377,18 +378,18 @@ private:
     /// Vector of callout vectors.  There is one entry in this outer vector for
     /// each hook. Each element is itself a vector, with one entry for each
     /// callout registered for that hook.
-    std::vector<CalloutVector>  hook_vector_;
+    std::vector<CalloutVector> hook_vector_;
 
     /// LibraryHandle object user by the callout to access the callout
     /// registration methods on this CalloutManager object.  The object is set
     /// such that the index of the library associated with any operation is
     /// whatever is currently set in the CalloutManager.
     LibraryHandle library_handle_;
-    
+
     /// LibraryHandle for callouts to be registered as being called before
     /// the user-registered callouts.
     LibraryHandle pre_library_handle_;
-    
+
     /// LibraryHandle for callouts to be registered as being called after
     /// the user-registered callouts.
     LibraryHandle post_library_handle_;
diff --git a/src/lib/hooks/hooks.h b/src/lib/hooks/hooks.h
index dcb27cb..e6658ca 100644
--- a/src/lib/hooks/hooks.h
+++ b/src/lib/hooks/hooks.h
@@ -18,7 +18,21 @@
 #include <hooks/callout_handle.h>
 #include <hooks/library_handle.h>
 
+namespace {
+
 // Version 1 of the hooks framework.
-static const int BIND10_HOOKS_VERSION = 1;
+const int BIND10_HOOKS_VERSION = 1;
+
+// Names of the framework functions.
+const char* LOAD_FUNCTION_NAME = "load";
+const char* UNLOAD_FUNCTION_NAME = "unload";
+const char* VERSION_FUNCTION_NAME = "version";
+
+// Typedefs for pointers to the framework functions.
+typedef int (*version_function_ptr)();
+typedef int (*load_function_ptr)(isc::hooks::LibraryHandle&);
+typedef int (*unload_function_ptr)();
+
+} // Anonymous namespace
 
 #endif  // HOOKS_H
diff --git a/src/lib/hooks/hooks_component_developer.dox b/src/lib/hooks/hooks_component_developer.dox
index 244e86b..edf59a8 100644
--- a/src/lib/hooks/hooks_component_developer.dox
+++ b/src/lib/hooks/hooks_component_developer.dox
@@ -17,60 +17,65 @@
 
 @section hooksComponentIntroduction Introduction
 
-The hooks framework is a BIND 10 library that simplifies the way that
+The hooks framework is a BIND 10 system that simplifies the way that
 users can write code to modify the behavior of BIND 10.  Instead of
 altering the BIND 10 source code, they write functions that are compiled
 and linked into a shared library.  The library is specified in the BIND 10
 configuration database and run time, BIND 10 dynamically loads the library
-into its address space.  At various points in the processing, the server
+into its address space.  At various points in the processing, the component
 "calls out" to functions in the library, passing to them the data is it
 currently working on.  They can examine and modify the data as required.
 
-The document @ref hooksDevelopersGuide describes how to write a library
-that interfaces into a BIND 10 component.  This guide describes how to
-write or modify a BIND 10 component so that it can load a shared library
-and call out to functions in it.
+This guide is aimed at BIND 10 developers who want to write or modify a
+BIND 10 component to use hooks.  It shows how the component should be written
+to load a shared library at run-time and how to call functions in it.
+
+For information about writing a hooks library containing functions called by BIND 10
+during its execution, see the document @ref hooksDevelopersGuide.
 
 @subsection hooksComponentTerminology Terminology
 
 In the remainder of this guide, the following terminology is used:
 
+- Component - a BIND 10 process, e.g. the authoritative DNS server or the
+DHCPv4 server.
+
 - Hook/Hook Point - used interchageably, this is a point in the code at
 which a call to user-written functions is made. Each hook has a name and
 each hook can have any number (including 0) of user-written functions
 attached to it.
 
-- Callout - a user-written function called by the server at a hook
-point. This is so-named because the server "calls out" to the library
+- Callout - a user-written function called by the component at a hook
+point. This is so-named because the component "calls out" to the library
 to execute a user-written function.
 
-- Component - a BIND 10 process, e.g. the authoritative server or the
-DHCPv4 server.
-
 - User code/user library - non-BIND 10 code that is compiled into a
 shared library and loaded by BIND 10 into its address space.  Multiple
 user libraries can be loaded at the same time, each containing callouts for
 the same hooks.  The hooks framework calls these libraries one after the
-other. (See the document @hooksDevelopersGuide for more details.)
+other. (See the document @ref hooksDevelopersGuide for more details.)
 
 @subsection hooksComponentLanguages Languages
 
 The core of BIND 10 is written in C++ with some parts in Python.  While it is
 the intention to provide the hooks framework for all languages, the initial
-versions are for C++.  All examples in this guide are in that language.
+version is for C++.  All examples in this guide are in that language.
 
 @section hooksComponentBasicIdeas Basic Ideas
 
 From the point of view of the component author, the basic ideas of the hooks
 framework are quite simple:
 
-- The hook points need to be defined.
+- The location of hook points in the code need to be determined.
 
-- At each hook point, the component needs to:
-  - copy data into the object used to pass information to the callout.
-  - call the callout.
-  - copy data back from the object used to exchange information.
-  - take action based on information returned.
+- Name the hook points and register them.
+
+- At each hook point, the component needs to complete the following steps to
+  execute callouts registered by the user-library:
+  -# copy data into the object used to pass information to the callout.
+  -# call the callout.
+  -# copy data back from the object used to exchange information.
+  -# take action based on information returned.
 
 Of course, to set up the system the libraries need to be loaded in the first
 place.  The component also needs to:
@@ -82,59 +87,64 @@ component.
 
 The following sections will describe these tasks in more detail.
 
- at section hooksComponentDefinition Defining the Hook Points
-
-Before any other action takes place, the hook points in the code need to be
-defined.  Each hook point has a name that must be unique amongst all hook
-points for the server, and the first step is to register those names.  The
-naming is done using the static method isc::hooks::HooksManager::registerHook():
+ at section hooksComponentDefinition Determing the Hook Points
+
+Before any other action takes place, the location of the hook points
+in the code need to be determined.  This of course depends on the
+component but as a general guideline, hook locations should be chosen
+where a callout is able to obtain useful information from BIND 10 and/or
+affect processing.  Typically this means at the start or end of a major
+step in the processing of a request, at a point where either useful
+information can be passed to a callout and/or the callout can affect
+the processing of the component. The latter is achieved in either or both
+of the following eays:
+
+- Setting the "skip" flag.  This is a boolean flag that the callout can set
+  and is a quick way of passing information back to the component.  It is used
+  to indicate that the component should skip the processing step associated with
+  the hook.  The exact action is up to the component, but is likely to be one
+  of skipping the processing step (probably because the callout has
+  done its own processing for the action) or dropping the current packet
+  and starting on a new request.
+
+- Modifying data passed to it.  The component should be prepared to continue
+  processing with the data returned by the callout.  It is up to the component
+  author whether the data is validated before being used, but doing so will
+  have performance implications.
+
+ at section hooksComponentRegistration Naming and Registering the Hooks Points
+
+Once the location of the hook point has been determined, it should be
+given a name.  This name should be unique amongst all hook points and is
+subject to certain restrictions (see below).
+
+Before the callouts at any hook point are called and any user libraries
+loaded - so typically during component initialization - the component must
+register the names of all the hooks.  The registration is done using
+the static method isc::hooks::HooksManager::registerHook():
 
 @code
 
 #include <hooks/hooks_manager.h>
     :
-    int example_index = HooksManager::registerHook("manager");
+    int example_index = HooksManager::registerHook("lease_allocate");
 @endcode
 
-The name of the hooks is passed as the sole argument to the
-HooksManager::registerHook() method.  The value returned is the index of that
-hook point and should be retained - it is needed to call the hook.
-
-All hooks used by the component must be registered before the component
-starts operations.
-
- at subsection hooksComponentHookNames Hook Names
+The name of the hook is passed as the sole argument to the registerHook()
+method.  The value returned is the index of that hook point and should
+be retained - it is needed to call the callouts attached to that hook.
 
-Hook names are strings and in principle, any string can be used as the
-name of a hook, even one containing spaces and non-printable characters.
-However, the following guidelines should be observed:
-
-- The names <b>context_create</b> and <b>context_destroy</b> are reserved to
-the hooks system and are automatically registered: an attempt to register
-one of these will lead to a isc::hooks::DuplicateHook exception being thrown.
-
-- The hook name should be a valid function name in C.  If a user gives a
-callout the same name as one of the hooks, the hooks framework will
-automatically load that callout and attach it to the hook: the user does not
-have to explicitly register it. <b>TBD: do we still want this given
-the possibility of confusion with functions in system libraries?</b>
-
-- The hook name should not conflict with the name of a function in any of
-the system libraries (e.g. naming a hook "sqrt" could lead to the
-square-root function in the system's maths library being attached to the hook
-as a callout).
-
-- Although hook names can be in any case (including mixed case), the BIND 10
-convention is that they are lower-case.
+Note that a hook only needs to be registered once.  There is no mechanism for
+unregistering a hook and there is no need to do so.
 
 @subsection hooksComponentAutomaticRegistration Automatic Registration of Hooks
 
-In some components, it may be convenient to set up a separate
-initialization function that registers all hooks.  For others, it may
-be more convenient for each module within the component to perform its
-own initialization.  Since the HooksManager object is a singleton and
-is created when first requested, a useful trick is to automatically
-register the hooks when the module is loaded.
+In some components, it may be convenient to set up a single initialization
+function that registers all hooks.  For others, it may be more convenient
+for each module within the component to perform its own initialization.
+Since the isc::hooks::HooksManager object is a singleton and is created when first
+accessed, a useful trick is to automatically register the hooks when
+the module is loaded.
 
 This technique involves declaring an object outside of any execution
 unit in the module.  When the module is loaded, the object's constructor
@@ -151,8 +161,8 @@ namespace {
 // Declare structure to perform initialization and store the hook indexes.
 //
 struct MyHooks {
-    int pkt_rcvd;   // Packet received
-    int pkt_sent;   // Packet sent
+    int pkt_rcvd;   // Index of "packet received" hook
+    int pkt_sent;   // Index of "packet sent" hook
 
     // Constructor
     MyHooks() {
@@ -161,23 +171,47 @@ struct MyHooks {
     }
 };
 
-// Instantiate a "Hooks" object.  The constructor is run when the module is
-// loaded and so the hook indexes will be defined before any method in this
+// Declare a "MyHooks" object.  As this is outside any function or method, it
+// will be instantiated (and the constructor run) when the module is loaded.
+// As a result, the hook indexes will be defined before any method in this
 // module is called.
-Hooks hooks;
+MyHooks my_hooks;
 
 } // Anonymous namespace
 
 void Someclass::someFunction() {
     :
     // Check if any callouts are defined on the pkt_rcvd hook.
-    if (HooksManager::calloutPresent(hooks.pkt_rcvd)) {
+    if (HooksManager::calloutPresent(my_hooks.pkt_rcvd)) {
           :
     }
     :
 }
 @endcode
 
+ at subsection hooksComponentHookNames Hook Names
+
+Hook names are strings and in principle, any string can be used as the
+name of a hook, even one containing spaces and non-printable characters.
+However, the following guidelines should be observed:
+
+- The names <b>context_create</b> and <b>context_destroy</b> are reserved to
+the hooks system and are automatically registered: an attempt to register
+one of these will lead to a isc::hooks::DuplicateHook exception being thrown.
+
+- The hook name should be a valid "C" function name.  If a user gives a
+callout the same name as one of the hooks, the hooks framework will
+automatically load that callout and attach it to the hook: the user does not
+have to explicitly register it.
+
+- The hook name should not conflict with the name of a function in any of
+the system libraries (e.g. naming a hook "sqrt" could lead to the
+square-root function in the system's maths library being attached to the hook
+as a callout).
+
+- Although hook names can be in any case (including mixed case), the BIND 10
+convention is that they are lower-case.
+
 @section hooksComponentCallingCallouts Calling Callouts on a Hook
 
 @subsection hooksComponentArgument The Callout Handle
@@ -187,12 +221,16 @@ how to pass data to it.
 
 Each user callout has the signature:
 @code
-int callout_name(CalloutHandle& handle);
+int callout_name(isc::hooks::CalloutHandle& handle);
 @endcode
 
 The isc::hooks::CalloutHandle object is the object used to pass data to
 and from the callout.  This holds the data as a set of name/value pairs,
-each pair being considered an argument to the callout.
+each pair being considered an argument to the callout.  If there are
+multiple callouts attached to a hook, the CalloutHandle is passed to
+each in turn. Should a callout modify an argument, the updated data is
+passed subsequent callouts (each of which could also modify it) before
+being returned to the component.
 
 Two methods are provided to get and set the arguments passed to
 the callout called (naturally enough) getArgument and SetArgument.
@@ -202,23 +240,25 @@ Their usage is illustrated by the following code snippets.
     int count = 10;
     boost::shared_ptr<Pkt4> pktptr = ... // Set to appropriate value
 
-    // Assume that "handle" has been created
-    handle.setArgument("data_count", count);
-    handle.setArgument("inpacket", pktptr);
+    // Assume that "handle_ptr" has been created and is a pointer to a
+    // CalloutHandle.
+    handle_ptr->setArgument("data_count", count);
+    handle_ptr->setArgument("inpacket", pktptr);
 
-    // Call the hook code...
-    ...
+    // Call the hook code.  lease_assigned_index is the value returned from
+    // HooksManager::registerHook() when the hook was registered.
+    HooksManager::callCallouts(lease_assigned_index, *handle_ptr);
 
     // Retrieve the modified values
-    handle.getArgument("data_count", count);
-    handle.getArgument("inpacket", pktptr);
+    handle_ptr->getArgument("data_count", count);
+    handle_ptr->getArgument("inpacket", pktptr);
 @endcode
 
 As can be seen "getArgument" is used to retrieve data from the
-isc::hooks::CalloutHandle, and setArgument used to put data into it.
-If a callout wishes to alter data and pass it back to the server,
-it should retrieve the data with getArgument, modify it, and call
-setArgument to send it back.
+CalloutHandle, and "setArgument" used to put data into it.  If a callout
+wishes to alter data and pass it back to the component, it should retrieve
+the data with getArgument, modify it, and call setArgument to send
+it back.
 
 There are a couple points to be aware of:
 
@@ -234,7 +274,7 @@ data pointed to by pointers, e.g. if an argument is defined as a "char*",
 an exception will be thrown if an attempt is made to retrieve it into
 a variable of type "const char*".  (However, if an argument is set as a
 "const int", it can be retrieved into an "int".)  The documentation of
-each hook point should detail the exact data type of each argument.
+a hook point should detail the exact data type of each argument.
 
 - If a pointer to an object is passed to a callout (either a "raw"
 pointer, or a boost smart pointer (as in the example above), and the
@@ -242,6 +282,47 @@ underlying object is altered through that pointer, the change will be
 reflected in the component even if the callout makes no call to setArgument.
 This can be avoided by passing a pointer to a "const" object.
 
+ at subsection hooksComponentSkipFlag The Skip Flag
+
+Although information is passed back to the component from callouts through
+CalloutHandle arguments, a common action for callouts is to inform the component
+that its flow of control should be altered.  For example:
+
+- In the DHCP servers, there is a hook at the point at which a lease is
+  about to be assigned.  Callouts attached to this hooks may handle the
+  lease assignment in special cases, in which case they set the skip flag
+  to indicate that the server should not perform lease assignment in this
+  case.
+- A server may define a hook just after a packet is received.  A callout
+  attached to the hook might inspect the source address and compare it
+  against a blacklist.  If the address is on the list, the callout could set
+  the skip flag to indicate to the server that the packet should be dropped.
+
+For ease of processing, the CalloutHandle contains
+two methods, isc::hooks::CalloutHandle::getSkip() and
+isc::hooks::CalloutHandle::setSkip().  It is only meaningful for the
+component to use the "get" method.  The skip flag is cleared by the hooks
+framework when the component requests that callouts be executed, so any
+value set by the component is lost.  Callouts can both inspect the flag (it
+might have been set by callouts earlier in the callout list for the hook)
+and set it.  Note that the setting of the flag by a callout does not
+prevent callouts later in the list from being called: the skip flag is
+just a boolean flag - the only significance comes from its interpretation
+by the component.
+
+An example of use could be:
+ at code
+// Set up arguments for DHCP lease assignment.
+handle->setArgument("query", query);
+handle->setArgument("response", response);
+HooksManager::callCallouts(lease_hook_index, *handle_ptr);
+if (! handle_ptr->getSkip()) {
+    // Skip flag not set, do the address allocation
+    :
+}
+ at endcode
+
+
 @subsection hooksComponentGettingHandle Getting the Callout Handle
 
 The CalloutHandle object is linked to the loaded libraries
@@ -249,15 +330,17 @@ for lifetime reasons (described below).  Components
 should retrieve a isc::hooks::CalloutHandle using
 isc::hooks::HooksManager::createCalloutHandle():
 @code
-    CalloutHandlePtr handle = HooksManager::createCalloutHandle();
+    CalloutHandlePtr handle_ptr = HooksManager::createCalloutHandle();
 @endcode
-(isc::hooks::CalloutHandlePtr is a typedef for a boost shared pointer to a
+(isc::hooks::CalloutHandlePtr is a typedef for a Boost shared pointer to a
 CalloutHandle.)  The CalloutHandle so retrieved may be used for as
 long as the libraries are loaded.
+
+The handle is deleted by resetting the pointer:
 @code
-    handle.reset();
+    handle_ptr.reset();
 @endcode
-... or by letting the handle object go out of scope.  The actual deletion
+... or by letting the handle pointer go out of scope.  The actual deletion
 occurs when the CallHandle's reference count goes to zero. (The
 current version of the hooks framework does not maintain any other
 pointer to the returned CalloutHandle, so it gets destroyed when the
@@ -271,52 +354,25 @@ isc::hooks::HooksManager::callCallouts() method for the hook index in
 question.  For example, with the hook index pkt_sent defined as above,
 the hook can be executed by:
 @code
-    HooksManager::callCallouts(pkt_rcvd, *handle);
+    HooksManager::callCallouts(pkt_sent, *handle_ptr);
 @endcode
-... where "*handle" is a reference (note: not a pointer) to the
+... where "*handle_ptr" is a reference (note: not a pointer) to the
 isc::hooks::CalloutHandle object holding the arguments.  No status code
-is returned.  If a component needs to get data returned, it should define
-an argument through which the callout can do so.
-
-Actually, the statement "no status code is returned" is not strictly true. At
-many hooks, the following logic applies:
- at code
-call hook_code
-if (hook_code has not performed an action) {
-    perform the action
-}
- at endcode
-For example, in a DHCP server an address should be allocated for a client.
-The DHCP server does that by default, but the hook code may want to override
-it in some situations.
-
-As this logic is so common, the CalloutHandle includes a "skip" flag.  This
-is a boolean flag that can be set by the callout to pass a basic yes/no
-response to the component.  Its use is illustrated by the following code
-snippet:
- at code
-// Set up arguments for lease assignment
-handle->setArgument("query", query);
-handle->setArgument("response", response);
-HooksManager::callCallouts(lease_hook_index, *handle);
-if (! handle->getSkip()) {
-    // Skip flag not set, do the address allocation
-    :
-}
- at endcode
-<b>SHOULD WE GET RID OF THE SKIP FLAG AND WHERE APPROPRIATE, SIGNAL SUCH
-PROCESSING THROUGH AN ARGUMENT?</b>
+is returned.  If a component needs to get data returned (other than that
+provided by the "skip" flag), it should define an argument through which
+the callout can do so.
 
 @subsubsection hooksComponentConditionalCallout Conditionally Calling Hook Callouts
 
-Most hooks in a server will not have callouts attached to them. To avoid the
-overhead of setting up arguments in the CalloutHandle, a component can
-check for callouts before doing that processing.  The
-isc::hooks::HooksManager::calloutsPresent() method performs this check.
-Taking the index of a hook as its sole argument, it returns true if there
-are any callouts attached to the hook and false otherwise.
+Most hooks in a component will not have callouts attached to them. To
+avoid the overhead of setting up arguments in the CalloutHandle, a
+component can check for callouts before doing that processing using
+isc::hooks::HooksManager::calloutsPresent().  Taking the index of a
+hook as its sole argument, the function returns true if there are any
+callouts attached to the hook and false otherwise.
 
-With this check, the above example can be modified to:
+With this check, the code in the component for calling a hook would look
+something like:
 @code
 if (HooksManager::calloutsPresent(lease_hook_index)) {
     // Set up arguments for lease assignment
@@ -332,7 +388,7 @@ if (HooksManager::calloutsPresent(lease_hook_index)) {
 
 @section hooksComponentLoadLibraries Loading the User Libraries
 
-Once hooks are defined, all the hooks code describe above will
+Once hooks are defined, all the hooks code described above will
 work, even if no libraries are loaded (and even if the library
 loading method is not called).  The CalloutHandle returned by
 isc::hooks::HooksManager::createCalloutHandle() will be valid,
@@ -365,8 +421,8 @@ loadLibraries() with an empty vector as an argument.
 @subsection hooksComponentUnloadIssues Unload and Reload Issues
 
 Unloading a shared library works by unmapping the part of the process's
-virtual address space in which the library lies.  This may lead to problems
-consequences if there are still references to that address space elsewhere
+virtual address space in which the library lies.  This may lead to
+problems if there are still references to that address space elsewhere
 in the process.
 
 In many operating systems, heap storage allowed by a shared library will
@@ -376,21 +432,21 @@ in the hooks framework because:
 - Argument information stored in a CalloutHandle by a callout in a library
 may lie in the library's address space.
 - Data modified in objects passed as arguments may lie in the address
-space.  For example, it is common for a DHCP callout to add "options" to
-a packet: the memory allocated for those options will like in library address
-space.
+space.  For example, it is common for a DHCP callout to add "options"
+to a packet: the memory allocated for those options will most likely
+lie in library address space.
 
 The problem really arises because of the extensive use by BIND 10 of boost
 smart pointers.  When the pointer is destroyed, the pointed-to memory is
 deallocated.  If the pointer points to address space that is unmapped because
 a library has been unloaded, the deletion causes a segmentation fault.
 
-The hooks framework addresses the issue for CalloutHandles by keeping
-in that object a shared pointer to the object controlling library
-unloading.  Although a library can be unloaded at any time, it is only when
-all CalloutHandles that could possibly reference address space in the
-library have been deleted that the library will be unloaded and the address
-space unmapped.
+The hooks framework addresses the issue for CalloutHandles by keeping in
+that object a shared pointer to the object controlling library unloading.
+Although a library can be unloaded at any time, it is only when all
+CalloutHandles that could possibly reference address space in the library
+have been deleted that the library will actually be unloaded and the
+address space unmapped.
 
 The hooks framework cannot solve the second issue as the objects in
 question are under control of the component.  It is up to the component
@@ -421,7 +477,7 @@ the LibraryHandle to register and deregister callouts is described in
 
 Finally, it should be noted that callouts registered in this way only
 remain registered until the next call to isc::hooks::loadLibraries().
-It is up to the server to re-register the callouts after this
+It is up to the component to re-register the callouts after this
 method has been called.
 
 */
diff --git a/src/lib/hooks/hooks_messages.mes b/src/lib/hooks/hooks_messages.mes
index 90402cb..33c1282 100644
--- a/src/lib/hooks/hooks_messages.mes
+++ b/src/lib/hooks/hooks_messages.mes
@@ -14,7 +14,7 @@
 
 $NAMESPACE isc::hooks
 
-% HOOKS_CALLOUT hooks library with index %1 has called a callout on hook %2 that has address %3
+% HOOKS_CALLOUT_CALLED hooks library with index %1 has called a callout on hook %2 that has address %3
 Only output at a high debugging level, this message indicates that
 a callout on the named hook registered by the library with the given
 index (in the list of loaded libraries) has been called and returned a
@@ -26,10 +26,12 @@ is issued.  It identifies the hook to which the callout is attached, the
 index of the library (in the list of loaded libraries) that registered
 it and the address of the callout.  The error is otherwise ignored.
 
-% HOOKS_CALLOUT_REMOVED callout removed from hook %1 for library %2
+% HOOKS_CALLOUTS_REMOVED callouts removed from hook %1 for library %2
 This is a debug message issued during library unloading.  It notes that
 one of more callouts registered by that library have been removed from
-the specified hook.
+the specified hook.  This is similar to the HOOKS_DEREGISTER_ALL_CALLOUTS
+message (and the two are likely to be seen together), but is issued at a
+higher-level in the hook framework.
 
 % HOOKS_CLOSE_ERROR failed to close hook library %1: %2
 BIND 10 has failed to close the named hook library for the stated reason.
@@ -43,14 +45,16 @@ issued.  It identifies the hook to which the callout is attached, the
 index of the library (in the list of loaded libraries) that registered
 it and the address of the callout.  The error is otherwise ignored.
 
-% HOOKS_DEREGISTER_ALL_CALLOUTS hook library at index %1 deregistered all callouts on hook %2
+% HOOKS_ALL_CALLOUTS_DEREGISTERED hook library at index %1 removed all callouts on hook %2
 A debug message issued when all callouts on the specified hook registered
-by the library with the given index were removed.
+by the library with the given index were removed.  This is similar to
+the HOOKS_CALLOUTS_REMOVED message (and the two are likely to be seen
+together), but is issued at a lower-level in the hook framework.
 
-% HOOKS_DEREGISTER_CALLOUT hook library at index %1 deregistered a callout on hook %2
+% HOOKS_CALLOUT_DEREGISTERED hook library at index %1 deregistered a callout on hook %2
 A debug message issued when all instances of a particular callouts on
 the hook identified in the message that were registered by the library
-with the given index were removed.
+with the given index have been removed.
 
 % HOOKS_INCORRECT_VERSION hook library %1 is at version %2, require version %3
 BIND 10 has detected that the named hook library has been built against
@@ -73,7 +77,7 @@ has been successfully unloaded.
 A debug  message issued when the version check on the hooks library
 has succeeded.
 
-% HOOKS_LOAD 'load' function in hook library %1 returned success
+% HOOKS_LOAD_SUCCESS 'load' function in hook library %1 returned success
 This is a debug message issued when the "load" function has been found
 in a hook library and has been successfully called.
 
@@ -83,8 +87,16 @@ was called.  The function returned a non-zero status (also given in
 the message) which was interpreted as an error.  The library has been
 unloaded and no callouts from it will be installed.
 
-% HOOKS_LOAD_LIBRARY loading hooks library %1
-This is a debug message called when the specified library is being loaded.
+% HOOKS_LOAD_EXCEPTION 'load' function in hook library %1 threw an exception
+A "load" function was found in the library named in the message and
+was called.  The function threw an exception (an error indication)
+during execution, which is an error condition.  The library has been
+unloaded and no callouts from it will be installed.
+
+% HOOKS_LIBRARY_LOADING loading hooks library %1
+This is a debug message output just before the specified library is loaded.
+If the action is successfully, it will be followed by the
+HOOKS_LIBRARY_LOADED informational message.
 
 % HOOKS_NO_LOAD no 'load' function found in hook library %1
 This is a debug message saying that the specified library was loaded
@@ -108,27 +120,27 @@ BIND 10 failed to open the specified hook library for the stated
 reason. The library has not been loaded.  BIND 10 will continue to
 function, but without the services offered by the library.
 
-% HOOKS_REGISTER_CALLOUT hooks library with index %1 registered callout for hook '%2'
+% HOOKS_CALLOUT_REGISTRATION hooks library with index %1 registering callout for hook '%2'
 This is a debug message, output when a library (whose index in the list
 of libraries (being) loaded is given) registers a callout.
 
-% HOOKS_REGISTER_HOOK hook %1 was registered
+% HOOKS_HOOK_REGISTERED hook %1 was registered
 This is a debug message indicating that a hook of the specified name
 was registered by a BIND 10 server.  The server doing the logging is
 indicated by the full name of the logger used to log this message.
 
-% HOOKS_REGISTER_STD_CALLOUT hooks library %1 registered standard callout for hook %2
+% HOOKS_STD_CALLOUT_REGISTERED hooks library %1 registered standard callout for hook %2 at address %3
 This is a debug message, output when the library loading function has
 located a standard callout (a callout with the same name as a hook point)
-and registered it.
+and registered it.  The address of the callout is indicated.
 
-% HOOKS_RESET_HOOK_LIST the list of hooks has been reset
+% HOOKS_HOOK_LIST_RESET the list of hooks has been reset
 This is a message indicating that the list of hooks has been reset.
 While this is usual when running the BIND 10 test suite, it should not be
 seen when running BIND 10 in a producion environment.  If this appears,
 please report a bug through the usual channels.
 
-% HOOKS_UNLOAD 'unload' function in hook library %1 returned success
+% HOOKS_UNLOAD_SUCCESS 'unload' function in hook library %1 returned success
 This is a debug message issued when an "unload" function has been found
 in a hook library during the unload process, called, and returned success.
 
@@ -138,6 +150,18 @@ It was called, but returned an error (non-zero) status, resulting in
 the issuing of this message.  The unload process continued after this
 message and the library has been unloaded.
 
-% HOOKS_UNLOAD_LIBRARY unloading library %1
-This is a debug message called when the specified library is being
-unloaded.
+% HOOKS_UNLOAD_EXCEPTION 'unload' function in hook library %1 threw an exception
+During the unloading of a library, an "unload" function was found.  It was
+called, but in the process generated an exception (an error indication).
+The unload process continued after this message and the library has
+been unloaded.
+
+% HOOKS_LIBRARY_UNLOADING unloading library %1
+This is a debug message called when the specified library is
+being unloaded.  If all is successful, it will be followed by the
+HOOKS_LIBRARY_UNLOADED informational message.
+
+% HOOKS_VERSION_EXCEPTION 'version' function in hook library %1 threw an exception
+This error message is issued if the version() function in the specified
+hooks library was called and generated an exception.  The library is
+considered unusable and will not be loaded.
diff --git a/src/lib/hooks/library_manager.cc b/src/lib/hooks/library_manager.cc
index 59fafa9..517b107 100644
--- a/src/lib/hooks/library_manager.cc
+++ b/src/lib/hooks/library_manager.cc
@@ -24,20 +24,84 @@
 
 #include <dlfcn.h>
 
-namespace {
-
-// String constants
-
-const char* LOAD_FUNCTION_NAME = "load";
-const char* UNLOAD_FUNCTION_NAME = "unload";
-const char* VERSION_FUNCTION_NAME = "version";
-}
-
 using namespace std;
 
 namespace isc {
 namespace hooks {
 
+/// @brief Local class for conversion of void pointers to function pointers
+///
+/// Converting between void* and function pointers in C++ is fraught with
+/// difficulty and pitfalls, e.g. see
+/// https://groups.google.com/forum/?hl=en&fromgroups#!topic/comp.lang.c++/37o0l8rtEE0
+///
+/// The method given in that article - convert using a union is used here.  A
+/// union is declared (and zeroed) and the appropriate member extracted when
+/// needed.
+
+class PointerConverter {
+public:
+    /// @brief Constructor
+    ///
+    /// Zeroes the union and stores the void* pointer we wish to convert (the
+    /// one returned by dlsym).
+    ///
+    /// @param dlsym_ptr void* pointer returned by call to dlsym()
+    PointerConverter(void* dlsym_ptr) {
+        memset(&pointers_, 0, sizeof(pointers_));
+        pointers_.dlsym_ptr = dlsym_ptr;
+    }
+
+    /// @name Pointer accessor functions
+    ///
+    /// It is up to the caller to ensure that the correct member is called so
+    /// that the correct trype of pointer is returned.
+    ///
+    ///@{
+
+    /// @brief Return pointer to callout function
+    ///
+    /// @return Pointer to the callout function
+    CalloutPtr calloutPtr() const {
+        return (pointers_.callout_ptr);
+    }
+
+    /// @brief Return pointer to load function
+    ///
+    /// @return Pointer to the load function
+    load_function_ptr loadPtr() const {
+        return (pointers_.load_ptr);
+    }
+
+    /// @brief Return pointer to unload function
+    ///
+    /// @return Pointer to the unload function
+    unload_function_ptr unloadPtr() const {
+        return (pointers_.unload_ptr);
+    }
+
+    /// @brief Return pointer to version function
+    ///
+    /// @return Pointer to the version function
+    version_function_ptr versionPtr() const {
+        return (pointers_.version_ptr);
+    }
+
+    ///@}
+
+private:
+
+    /// @brief Union linking void* and pointers to functions.
+    union {
+        void*                   dlsym_ptr;      // void* returned by dlsym
+        CalloutPtr              callout_ptr;    // Pointer to callout
+        load_function_ptr       load_ptr;       // Pointer to load function
+        unload_function_ptr     unload_ptr;     // Pointer to unload function
+        version_function_ptr    version_ptr;    // Pointer to version function
+    } pointers_;
+};
+
+
 // Open the library
 
 bool
@@ -78,28 +142,17 @@ LibraryManager::closeLibrary() {
 bool
 LibraryManager::checkVersion() const {
 
-    // Look up the "version" string in the library.  This is returned as
-    // "void*": without any other information, we must assume that it is of
-    // the correct type of version_function_ptr.
-    //
-    // Note that converting between void* and function pointers in C++ is
-    // fraught with difficulty and pitfalls (e.g. see
-    // https://groups.google.com/forum/?hl=en&fromgroups#!topic/
-    // comp.lang.c++/37o0l8rtEE0)
-    // The method given in that article - convert using a union is used here.
-    union {
-        version_function_ptr    ver_ptr;
-        void*                   dlsym_ptr;
-    } pointers;
-
-    // Zero the union, whatever the size of the pointers.
-    pointers.ver_ptr = NULL;
-    pointers.dlsym_ptr = NULL;
-
     // Get the pointer to the "version" function.
-    pointers.dlsym_ptr = dlsym(dl_handle_, VERSION_FUNCTION_NAME);
-    if (pointers.ver_ptr != NULL) {
-        int version = (*pointers.ver_ptr)();
+    PointerConverter pc(dlsym(dl_handle_, VERSION_FUNCTION_NAME));
+    if (pc.versionPtr() != NULL) {
+        int version = BIND10_HOOKS_VERSION - 1; // This is an invalid value
+        try {
+            version = (*pc.versionPtr())();
+        } catch (...) {
+            LOG_ERROR(hooks_logger, HOOKS_VERSION_EXCEPTION).arg(library_name_);
+            return (false);
+        }
+
         if (version == BIND10_HOOKS_VERSION) {
             // All OK, version checks out
             LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_LIBRARY_VERSION)
@@ -121,31 +174,23 @@ LibraryManager::checkVersion() const {
 
 void
 LibraryManager::registerStandardCallouts() {
-    // Create a library handle for doing the registration.  We also need to
-    // set the current library index to indicate the current library.
+    // Set the library index for doing the registration.  This is picked up
+    // when the library handle is created.
     manager_->setLibraryIndex(index_);
-    LibraryHandle library_handle(manager_.get());
 
-    // Iterate through the list of known hooksv
+    // Iterate through the list of known hooks
     vector<string> hook_names = ServerHooks::getServerHooks().getHookNames();
     for (int i = 0; i < hook_names.size(); ++i) {
 
-        // Convert void* to function pointers using the same tricks as
-        // described above.
-        union {
-            CalloutPtr  callout_ptr;
-            void*       dlsym_ptr;
-        } pointers;
-        pointers.callout_ptr = NULL;
-        pointers.dlsym_ptr = NULL;
-
         // Look up the symbol
-        pointers.dlsym_ptr = dlsym(dl_handle_, hook_names[i].c_str());
-        if (pointers.callout_ptr != NULL) {
+        void* dlsym_ptr = dlsym(dl_handle_, hook_names[i].c_str());
+        PointerConverter pc(dlsym_ptr);
+        if (pc.calloutPtr() != NULL) {
             // Found a symbol, so register it.
-            LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_REGISTER_STD_CALLOUT)
-                .arg(library_name_).arg(hook_names[i]);
-            library_handle.registerCallout(hook_names[i], pointers.callout_ptr);
+            manager_->getLibraryHandle().registerCallout(hook_names[i],
+                                                         pc.calloutPtr());
+            LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_STD_CALLOUT_REGISTERED)
+                .arg(library_name_).arg(hook_names[i]).arg(dlsym_ptr);
 
         }
     }
@@ -156,35 +201,32 @@ LibraryManager::registerStandardCallouts() {
 bool
 LibraryManager::runLoad() {
 
-    // Look up the "load" function in the library.  The code here is similar
-    // to that in "checkVersion".
-    union {
-        load_function_ptr   load_ptr;
-        void*               dlsym_ptr;
-    } pointers;
-
-    // Zero the union, whatever the size of the pointers.
-    pointers.load_ptr = NULL;
-    pointers.dlsym_ptr = NULL;
-
     // Get the pointer to the "load" function.
-    pointers.dlsym_ptr = dlsym(dl_handle_, LOAD_FUNCTION_NAME);
-    if (pointers.load_ptr != NULL) {
+    PointerConverter pc(dlsym(dl_handle_, LOAD_FUNCTION_NAME));
+    if (pc.loadPtr() != NULL) {
 
         // Call the load() function with the library handle.  We need to set
         // the CalloutManager's index appropriately.  We'll invalidate it
         // afterwards.
-        manager_->setLibraryIndex(index_);
-        int status = (*pointers.load_ptr)(manager_->getLibraryHandle());
-        manager_->setLibraryIndex(index_);
+
+        int status = -1;
+        try {
+            manager_->setLibraryIndex(index_);
+            status = (*pc.loadPtr())(manager_->getLibraryHandle());
+        } catch (...) {
+            LOG_ERROR(hooks_logger, HOOKS_LOAD_EXCEPTION).arg(library_name_);
+            return (false);
+        }
+
         if (status != 0) {
             LOG_ERROR(hooks_logger, HOOKS_LOAD_ERROR).arg(library_name_)
                       .arg(status);
             return (false);
         } else {
-        LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_LOAD)
+        LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_LOAD_SUCCESS)
             .arg(library_name_);
         }
+
     } else {
         LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_NO_LOAD)
             .arg(library_name_);
@@ -199,31 +241,29 @@ LibraryManager::runLoad() {
 bool
 LibraryManager::runUnload() {
 
-    // Look up the "load" function in the library.  The code here is similar
-    // to that in "checkVersion".
-    union {
-        unload_function_ptr unload_ptr;
-        void*               dlsym_ptr;
-    } pointers;
-
-    // Zero the union, whatever the relative size of the pointers.
-    pointers.unload_ptr = NULL;
-    pointers.dlsym_ptr = NULL;
-
     // Get the pointer to the "load" function.
-    pointers.dlsym_ptr = dlsym(dl_handle_, UNLOAD_FUNCTION_NAME);
-    if (pointers.unload_ptr != NULL) {
+    PointerConverter pc(dlsym(dl_handle_, UNLOAD_FUNCTION_NAME));
+    if (pc.unloadPtr() != NULL) {
 
         // Call the load() function with the library handle.  We need to set
         // the CalloutManager's index appropriately.  We'll invalidate it
         // afterwards.
-        int status = (*pointers.unload_ptr)();
+        int status = -1;
+        try {
+            status = (*pc.unloadPtr())();
+        } catch (...) {
+            // Exception generated.  Note a warning as the unload will occur
+            // anyway.
+            LOG_WARN(hooks_logger, HOOKS_UNLOAD_EXCEPTION).arg(library_name_);
+            return (false);
+        }
+
         if (status != 0) {
             LOG_ERROR(hooks_logger, HOOKS_UNLOAD_ERROR).arg(library_name_)
                       .arg(status);
             return (false);
         } else {
-        LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_UNLOAD)
+        LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_UNLOAD_SUCCESS)
             .arg(library_name_);
         }
     } else {
@@ -238,43 +278,44 @@ LibraryManager::runUnload() {
 
 bool
 LibraryManager::loadLibrary() {
-    LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_LOAD_LIBRARY)
+    LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_LIBRARY_LOADING)
         .arg(library_name_);
 
     // In the following, if a method such as openLibrary() fails, it will
     // have issued an error message so there is no need to issue another one
     // here.
 
+    // Open the library (which is a check that it exists and is accessible).
     if (openLibrary()) {
 
         // Library opened OK, see if a version function is present and if so,
-        // check it.
+        // check what value it returns.
         if (checkVersion()) {
 
             // Version OK, so now register the standard callouts and call the
-            // librarie's load() function if present.
+            // library's load() function if present.
             registerStandardCallouts();
             if (runLoad()) {
 
                 // Success - the library has been successfully loaded.
                 LOG_INFO(hooks_logger, HOOKS_LIBRARY_LOADED).arg(library_name_);
                 return (true);
+
             } else {
 
                 // The load function failed, so back out.  We can't just close
                 // the library as (a) we need to call the library's "unload"
                 // function (if present) in case "load" allocated resources that
-                // need to be freed and (b) - we need to remove any callouts
-                // that have been installed.
+                // need to be freed and (b) we need to remove any callouts that
+                // have been installed.
                 static_cast<void>(unloadLibrary());
             }
-        } else {
-
-            // Version check failed so close the library and free up resources.
-            // Ignore the status return here - we already have an error
-            // consition.
-            static_cast<void>(closeLibrary());
         }
+
+        // Either the version check or call to load() failed, so close the
+        // library and free up resources.  Ignore the status return here - we
+        // already know there's an error and will have output a message.
+        static_cast<void>(closeLibrary());
     }
 
     return (false);
@@ -285,7 +326,7 @@ LibraryManager::loadLibrary() {
 
 bool
 LibraryManager::unloadLibrary() {
-    LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_UNLOAD_LIBRARY)
+    LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_LIBRARY_UNLOADING)
         .arg(library_name_);
 
     // Call the unload() function if present.  Note that this is done first -
@@ -300,13 +341,13 @@ LibraryManager::unloadLibrary() {
     for (int i = 0; i < hooks.size(); ++i) {
         bool removed = manager_->deregisterAllCallouts(hooks[i]);
         if (removed) {
-            LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_CALLOUT_REMOVED)
+            LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_CALLOUTS_REMOVED)
                 .arg(hooks[i]).arg(library_name_);
         }
     }
 
     // ... and close the library.
-    result = result && closeLibrary();
+    result = closeLibrary() && result;
     if (result) {
 
         // Issue the informational message only if the library was unloaded
diff --git a/src/lib/hooks/library_manager.h b/src/lib/hooks/library_manager.h
index e4899a5..56c770b 100644
--- a/src/lib/hooks/library_manager.h
+++ b/src/lib/hooks/library_manager.h
@@ -35,8 +35,8 @@ class LibraryManager;
 /// known hooks and locates their symbols, registering each callout as it does
 /// so.  Finally it locates the "load" function (if present) and calls it.
 ///
-/// On unload, it calls the "unload" method if present, clears the callouts
-/// all hooks and closes the library.
+/// On unload, it calls the "unload" method if present, clears the callouts on
+/// all hooks, and closes the library.
 ///
 /// @note Caution needs to be exercised when using the unload method. During
 ///       normal use, data will pass between the server and the library.  In
@@ -46,7 +46,7 @@ class LibraryManager;
 ///       of pointed-to data. If the library is unloaded, this memory may lie
 ///       in the virtual address space deleted in that process. (The word "may"
 ///       is used, as this could be operating-system specific.) Should this
-///       happens, any reference to the memory will cause a segmentation fault.
+///       happen, any reference to the memory will cause a segmentation fault.
 ///       This can occur in a quite obscure place, for example in the middle of
 ///       a destructor of an STL class when it is deleting memory allocated
 ///       when the data structure was extended by a function in the library.
@@ -60,12 +60,6 @@ class LibraryManager;
 ///       reloading the libraries.
 
 class LibraryManager {
-private:
-    /// Useful typedefs for the framework functions
-    typedef int (*version_function_ptr)();            ///< version() signature
-    typedef int (*load_function_ptr)(LibraryHandle&); ///< load() signature
-    typedef int (*unload_function_ptr)();             ///< unload() signature
-
 public:
     /// @brief Constructor
     ///
@@ -146,7 +140,9 @@ protected:
     ///
     /// With the library open, accesses the "version()" function and, if
     /// present, checks the returned value against the hooks version symbol
-    /// for the currently running BIND 10.
+    /// for the currently running BIND 10.  The "version()" function is
+    /// mandatory and must be present (and return the correct value) for the
+    /// library to load.
     ///
     /// If there is no version() function, or if there is a mismatch in
     /// version number, a message logged.
diff --git a/src/lib/hooks/server_hooks.cc b/src/lib/hooks/server_hooks.cc
index 32901cc..1a0b157 100644
--- a/src/lib/hooks/server_hooks.cc
+++ b/src/lib/hooks/server_hooks.cc
@@ -55,7 +55,7 @@ ServerHooks::registerHook(const string& name) {
     inverse_hooks_[index] = name;
 
     // Log it if debug is enabled
-    LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_REGISTER_HOOK).arg(name);
+    LOG_DEBUG(hooks_logger, HOOKS_DBG_TRACE, HOOKS_HOOK_REGISTERED).arg(name);
 
     // ... and return numeric index.
     return (index);
@@ -65,9 +65,6 @@ ServerHooks::registerHook(const string& name) {
 
 void
 ServerHooks::reset() {
-    // Log a warning - although this is done during testing, it should never be
-    // seen in a production system.
-    LOG_WARN(hooks_logger, HOOKS_RESET_HOOK_LIST);
 
     // Clear out the name->index and index->name maps.
     hooks_.clear();
@@ -85,6 +82,10 @@ ServerHooks::reset() {
                   ". context_destroy: expected = " << CONTEXT_DESTROY <<
                   ", actual = " << destroy);
     }
+
+    // Log a warning - although this is done during testing, it should never be
+    // seen in a production system.
+    LOG_WARN(hooks_logger, HOOKS_HOOK_LIST_RESET);
 }
 
 // Find the name associated with a hook index.
diff --git a/src/lib/hooks/server_hooks.h b/src/lib/hooks/server_hooks.h
index 55a6cde..f075cb8 100644
--- a/src/lib/hooks/server_hooks.h
+++ b/src/lib/hooks/server_hooks.h
@@ -151,7 +151,7 @@ private:
     ///
     /// Constructor is declared private to enforce the singleton nature of
     /// the object.  A reference to the singleton is obtainable through the
-    /// ggetServerHooks() static method.
+    /// getServerHooks() static method.
     ///
     /// @throws isc::Unexpected if the registration of the pre-defined hooks
     ///         fails in some way.
diff --git a/src/lib/hooks/tests/Makefile.am b/src/lib/hooks/tests/Makefile.am
index ba23c30..8fe94b0 100644
--- a/src/lib/hooks/tests/Makefile.am
+++ b/src/lib/hooks/tests/Makefile.am
@@ -27,18 +27,23 @@ TESTS_ENVIRONMENT = \
 TESTS =
 if HAVE_GTEST
 # Build shared libraries for testing.
-lib_LTLIBRARIES = libnvl.la libivl.la libbcl.la liblcl.la liblecl.la \
+lib_LTLIBRARIES = libnvl.la libivl.la libfxl.la libbcl.la liblcl.la liblecl.la \
                   libucl.la libfcl.la
- 
+
 # No version function
 libnvl_la_SOURCES  = no_version_library.cc
 libnvl_la_CXXFLAGS = $(AM_CXXFLAGS)
 libnvl_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
- 
+
 # Incorrect version function
 libivl_la_SOURCES  = incorrect_version_library.cc
 libivl_la_CXXFLAGS = $(AM_CXXFLAGS)
-libilv_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+libivl_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
+
+# All framework functions throw an exception
+libfxl_la_SOURCES = framework_exception_library.cc
+libfxl_la_CXXFLAGS = $(AM_CXXFLAGS)
+libfxl_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
 
 # The basic callout library - contains standard callouts
 libbcl_la_SOURCES  = basic_callout_library.cc
diff --git a/src/lib/hooks/tests/basic_callout_library.cc b/src/lib/hooks/tests/basic_callout_library.cc
index ff39a9c..253de80 100644
--- a/src/lib/hooks/tests/basic_callout_library.cc
+++ b/src/lib/hooks/tests/basic_callout_library.cc
@@ -24,7 +24,7 @@
 /// - A context_create callout is supplied.
 ///
 /// - Three "standard" callouts are supplied corresponding to the hooks
-///   "lm_one", "lm_two", "lm_three".  All do some trivial calculations
+///   "hookpt_one", "hookpt_two", "hookpt_three".  All do some trivial calculations
 ///   on the arguments supplied to it and the context variables, returning
 ///   intermediate results through the "result" argument. The result of
 ///   executing all four callouts in order is:
@@ -32,8 +32,8 @@
 ///   @f[ (10 + data_1) * data_2 - data_3 @f]
 ///
 ///   ...where data_1, data_2 and data_3 are the values passed in arguments of
-///   the same name to the three callouts (data_1 passed to lm_one, data_2 to
-///   lm_two etc.) and the result is returned in the argument "result".
+///   the same name to the three callouts (data_1 passed to hookpt_one, data_2 to
+///   hookpt_two etc.) and the result is returned in the argument "result".
 
 #include <hooks/hooks.h>
 #include <fstream>
@@ -58,7 +58,7 @@ context_create(CalloutHandle& handle) {
 // between callouts in the same library.)
 
 int
-lm_one(CalloutHandle& handle) {
+hookpt_one(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_1", data);
 
@@ -75,7 +75,7 @@ lm_one(CalloutHandle& handle) {
 // argument.
 
 int
-lm_two(CalloutHandle& handle) {
+hookpt_two(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_2", data);
 
@@ -91,7 +91,7 @@ lm_two(CalloutHandle& handle) {
 // Final callout subtracts the result in "data_3".
 
 int
-lm_three(CalloutHandle& handle) {
+hookpt_three(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_3", data);
 
diff --git a/src/lib/hooks/tests/callout_handle_unittest.cc b/src/lib/hooks/tests/callout_handle_unittest.cc
index 69622d1..b24a4cf 100644
--- a/src/lib/hooks/tests/callout_handle_unittest.cc
+++ b/src/lib/hooks/tests/callout_handle_unittest.cc
@@ -83,7 +83,7 @@ TEST_F(CalloutHandleTest, ArgumentDistinctSimpleType) {
     EXPECT_EQ(142, d);
 
     // Add a short (random value).
-    short e = -81; 
+    short e = -81;
     handle.setArgument("short", e);
     EXPECT_EQ(-81, e);
 
diff --git a/src/lib/hooks/tests/callout_manager_unittest.cc b/src/lib/hooks/tests/callout_manager_unittest.cc
index 9f1f3ca..935987a 100644
--- a/src/lib/hooks/tests/callout_manager_unittest.cc
+++ b/src/lib/hooks/tests/callout_manager_unittest.cc
@@ -258,7 +258,7 @@ TEST_F(CalloutManagerTest, RegisterCallout) {
     EXPECT_TRUE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Check that calling the callouts returns as expected. (This is also a
     // test of the callCallouts method.)
     callout_value_ = 0;
@@ -312,7 +312,7 @@ TEST_F(CalloutManagerTest, CalloutsPresent) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Set up so that hooks "alpha", "beta" and "delta" have callouts attached
     // to them, and callout  "gamma" does not. (In the statements below, the
     // exact callouts attached to a hook are not relevant - only the fact
@@ -348,7 +348,7 @@ TEST_F(CalloutManagerTest, CallNoCallouts) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Call the callouts on an arbitrary hook and ensure that nothing happens.
     callout_value_ = 475;
     getCalloutManager()->callCallouts(alpha_index_, getCalloutHandle());
@@ -365,7 +365,7 @@ TEST_F(CalloutManagerTest, CallCalloutsSuccess) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Each library contributes one callout on hook "alpha".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(1);
@@ -409,7 +409,7 @@ TEST_F(CalloutManagerTest, CallCalloutsError) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Each library contributing one callout on hook "alpha". The first callout
     // returns an error (after adding its value to the result).
     callout_value_ = 0;
@@ -481,7 +481,7 @@ TEST_F(CalloutManagerTest, DeregisterSingleCallout) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Add a callout to hook "alpha" and check it is added correctly.
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
@@ -507,7 +507,7 @@ TEST_F(CalloutManagerTest, DeregisterSingleCalloutSameLibrary) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Add multiple callouts to hook "alpha".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
@@ -543,7 +543,7 @@ TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsSameLibrary) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Each library contributes one callout on hook "alpha".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
@@ -599,7 +599,7 @@ TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsMultipleLibraries) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Each library contributes two callouts to hook "alpha".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
@@ -628,7 +628,7 @@ TEST_F(CalloutManagerTest, DeregisterMultipleCalloutsMultipleLibraries) {
 TEST_F(CalloutManagerTest, DeregisterAllCallouts) {
     // Ensure that no callouts are attached to hook one.
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(alpha_index_));
-                 
+
     // Each library contributes two callouts to hook "alpha".
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
@@ -668,7 +668,7 @@ TEST_F(CalloutManagerTest, MultipleCalloutsLibrariesHooks) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Register callouts on the alpha hook.
     callout_value_ = 0;
     getCalloutManager()->setLibraryIndex(0);
@@ -744,7 +744,7 @@ TEST_F(CalloutManagerTest, LibraryHandleRegistration) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Check that calling the callouts returns as expected. (This is also a
     // test of the callCallouts method.)
     callout_value_ = 0;
@@ -794,7 +794,7 @@ TEST_F(CalloutManagerTest, LibraryHandleAlternateConstructor) {
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(beta_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(gamma_index_));
     EXPECT_FALSE(getCalloutManager()->calloutsPresent(delta_index_));
-                 
+
     // Check that calling the callouts returns as expected. (This is also a
     // test of the callCallouts method.)
     callout_value_ = 0;
@@ -862,7 +862,7 @@ TEST_F(CalloutManagerTest, LibraryHandlePrePostUserLibrary) {
                                                                 callout_four);
     getCalloutManager()->getPreLibraryHandle().registerCallout("alpha",
                                                                 callout_one);
-    
+
     // ... and set up a callout in between, on library number 2.
     LibraryHandle lh1(getCalloutManager().get(), 2);
     lh1.registerCallout("alpha", callout_five);
diff --git a/src/lib/hooks/tests/common_test_class.h b/src/lib/hooks/tests/common_test_class.h
index bcb8e56..803e25c 100644
--- a/src/lib/hooks/tests/common_test_class.h
+++ b/src/lib/hooks/tests/common_test_class.h
@@ -44,18 +44,18 @@ public:
         isc::hooks::ServerHooks& hooks =
             isc::hooks::ServerHooks::getServerHooks();
         hooks.reset();
-        lm_one_index_ = hooks.registerHook("lm_one");
-        lm_two_index_ = hooks.registerHook("lm_two");
-        lm_three_index_ = hooks.registerHook("lm_three");
+        hookpt_one_index_ = hooks.registerHook("hookpt_one");
+        hookpt_two_index_ = hooks.registerHook("hookpt_two");
+        hookpt_three_index_ = hooks.registerHook("hookpt_three");
     }
 
     /// @brief Call callouts test
     ///
     /// All of the loaded libraries for which callouts are called register four
     /// callouts: a context_create callout and three callouts that are attached
-    /// to hooks lm_one, lm_two and lm_three.  These four callouts, executed
-    /// in sequence, perform a series of calculations. Data is passed between
-    /// callouts in the argument list, in a variable named "result".
+    /// to hooks hookpt_one, hookpt_two and hookpt_three.  These four callouts,
+    /// executed in sequence, perform a series of calculations. Data is passed
+    /// between callouts in the argument list, in a variable named "result".
     ///
     /// context_create initializes the calculation by setting a seed
     /// value, called r0 here.  This value is dependent on the library being
@@ -63,20 +63,24 @@ public:
     /// the purpose being to avoid exceptions when running this test with no
     /// libraries loaded.
     ///
-    /// Callout lm_one is passed a value d1 and performs a simple arithmetic
+    /// Callout hookpt_one is passed a value d1 and performs a simple arithmetic
     /// operation on it and r0 yielding a result r1.  Hence we can say that
-    /// @f[ r1 = lm1(r0, d1) @f]
+    /// @f[ r1 = hookpt_one(r0, d1) @f]
     ///
-    /// Callout lm_two is passed a value d2 and peforms another simple
+    /// Callout hookpt_two is passed a value d2 and peforms another simple
     /// arithmetic operation on it and d2, yielding r2, i.e.
-    /// @f[ r2 = lm2(d1, d2) @f]
+    /// @f[ r2 = hookpt_two(d1, d2) @f]
     ///
-    /// lm_three does a similar operation giving @f[ r3 = lm3(r2, d3) @f].
+    /// hookpt_three does a similar operation giving
+    /// @f[ r3 = hookpt_three(r2, d3) @f].
     ///
-    /// The details of the operations lm1, lm2 and lm3 depend on the library.
-    /// However the sequence of calls needed to do this set of calculations
-    /// is identical regardless of the exact functions. This method performs
-    /// those operations and checks the results of each step.
+    /// The details of the operations hookpt_one, hookpt_two and hookpt_three
+    /// depend on the library, so the results obtained not only depend on
+    /// the data, but also on the library loaded.  This method is passed both
+    /// data and expected results.  It executes the three callouts in sequence,
+    /// checking the intermediate and final results.  Only if the expected
+    /// library has been loaded correctly and the callouts in it registered
+    /// correctly will be the results be as expected.
     ///
     /// It is assumed that callout_manager_ has been set up appropriately.
     ///
@@ -86,9 +90,9 @@ public:
     ///       allocated by loaded libraries while they are still loaded.
     ///
     /// @param manager CalloutManager to use for the test
-    /// @param r0...r3, d1..d3 Values and intermediate values expected.  They
-    ///        are ordered so that the variables appear in the argument list in
-    ///        the order they are used.
+    /// @param r0...r3, d1..d3 Data (dN) and expected results (rN) - both
+    ///        intermediate and final.  The arguments are ordered so that they
+    ///        appear in the argument list in the order they are used.
     void executeCallCallouts(
             const boost::shared_ptr<isc::hooks::CalloutManager>& manager,
             int r0, int d1, int r1, int d2, int r2, int d3, int r3) {
@@ -112,27 +116,27 @@ public:
 
         // Perform the first calculation.
         handle.setArgument("data_1", d1);
-        manager->callCallouts(lm_one_index_, handle);
+        manager->callCallouts(hookpt_one_index_, handle);
         handle.getArgument(RESULT, result);
-        EXPECT_EQ(r1, result) << "lm_one" << COMMON_TEXT;
+        EXPECT_EQ(r1, result) << "hookpt_one" << COMMON_TEXT;
 
         // ... the second ...
         handle.setArgument("data_2", d2);
-        manager->callCallouts(lm_two_index_, handle);
+        manager->callCallouts(hookpt_two_index_, handle);
         handle.getArgument(RESULT, result);
-        EXPECT_EQ(r2, result) << "lm_two" << COMMON_TEXT;
+        EXPECT_EQ(r2, result) << "hookpt_two" << COMMON_TEXT;
 
         // ... and the third.
         handle.setArgument("data_3", d3);
-        manager->callCallouts(lm_three_index_, handle);
+        manager->callCallouts(hookpt_three_index_, handle);
         handle.getArgument(RESULT, result);
-        EXPECT_EQ(r3, result) << "lm_three" << COMMON_TEXT;
+        EXPECT_EQ(r3, result) << "hookpt_three" << COMMON_TEXT;
     }
 
     /// Hook indexes.  These are are made public for ease of reference.
-    int lm_one_index_;
-    int lm_two_index_;
-    int lm_three_index_;
+    int hookpt_one_index_;
+    int hookpt_two_index_;
+    int hookpt_three_index_;
 };
 
 #endif // COMMON_HOOKS_TEST_CLASS_H
diff --git a/src/lib/hooks/tests/framework_exception_library.cc b/src/lib/hooks/tests/framework_exception_library.cc
new file mode 100644
index 0000000..e90fd36
--- /dev/null
+++ b/src/lib/hooks/tests/framework_exception_library.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2013  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+/// @file
+/// @brief Framework exception library
+///
+/// This is source of a test library for various test (LibraryManager and
+/// HooksManager).  The characteristics of the library produced from this
+/// file are:
+///
+/// - All three framework functions are supplied (version(), load() and
+///   unload()) and all generate an exception.
+
+#include <hooks/hooks.h>
+
+#include <exception>
+
+extern "C" {
+
+int
+version() {
+    throw std::exception();
+}
+
+int
+load(isc::hooks::LibraryHandle& handle) {
+    throw std::exception();
+}
+
+int
+unload() {
+    throw std::exception();
+}
+
+};
+
diff --git a/src/lib/hooks/tests/full_callout_library.cc b/src/lib/hooks/tests/full_callout_library.cc
index df7a76f..33d5660 100644
--- a/src/lib/hooks/tests/full_callout_library.cc
+++ b/src/lib/hooks/tests/full_callout_library.cc
@@ -34,8 +34,8 @@
 ///   @f[ ((7 * data_1) - data_2) * data_3 @f]
 ///
 ///   ...where data_1, data_2 and data_3 are the values passed in arguments of
-///   the same name to the three callouts (data_1 passed to lm_one, data_2 to
-///   lm_two etc.) and the result is returned in the argument "result".
+///   the same name to the three callouts (data_1 passed to hookpt_one, data_2 to
+///   hookpt_two etc.) and the result is returned in the argument "result".
 
 #include <hooks/hooks.h>
 #include <hooks/tests/marker_file.h>
@@ -61,7 +61,7 @@ context_create(CalloutHandle& handle) {
 // between callouts in the same library.)
 
 int
-lm_one(CalloutHandle& handle) {
+hookpt_one(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_1", data);
 
@@ -78,7 +78,7 @@ lm_one(CalloutHandle& handle) {
 // running total.
 
 static int
-lm_nonstandard_two(CalloutHandle& handle) {
+hook_nonstandard_two(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_2", data);
 
@@ -94,7 +94,7 @@ lm_nonstandard_two(CalloutHandle& handle) {
 // Final callout multplies the current running total by data_3.
 
 static int
-lm_nonstandard_three(CalloutHandle& handle) {
+hook_nonstandard_three(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_3", data);
 
@@ -117,8 +117,8 @@ version() {
 int
 load(LibraryHandle& handle) {
     // Register the non-standard functions
-    handle.registerCallout("lm_two", lm_nonstandard_two);
-    handle.registerCallout("lm_three", lm_nonstandard_three);
+    handle.registerCallout("hookpt_two", hook_nonstandard_two);
+    handle.registerCallout("hookpt_three", hook_nonstandard_three);
 
     return (0);
 }
diff --git a/src/lib/hooks/tests/handles_unittest.cc b/src/lib/hooks/tests/handles_unittest.cc
index 5c23bfe..b5203a9 100644
--- a/src/lib/hooks/tests/handles_unittest.cc
+++ b/src/lib/hooks/tests/handles_unittest.cc
@@ -301,10 +301,10 @@ TEST_F(HandlesTest, ContextAccessCheck) {
     // Create the callout handles and distinguish them by setting the
     // "handle_num" argument.
     CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1));
 
     CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2));
 
     // Now call the callouts attached to the first three hooks.  Each hook is
     // called twice (once for each callout handle) before the next hook is
@@ -606,7 +606,7 @@ TEST_F(HandlesTest, DynamicRegistrationAnotherHook) {
 
     // See what we get for calling the callouts on alpha first.
     CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1));
     getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
 
     zero_results();
@@ -622,7 +622,7 @@ TEST_F(HandlesTest, DynamicRegistrationAnotherHook) {
 
     // Use a new callout handle so as to get fresh callout context.
     CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2));
     getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
 
     zero_results();
@@ -654,7 +654,7 @@ TEST_F(HandlesTest, DynamicRegistrationSameHook) {
 
     // See what we get for calling the callouts on alpha first.
     CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1));
     getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
     zero_results();
     getCalloutManager()->callCallouts(delta_index_, callout_handle_1);
@@ -662,7 +662,7 @@ TEST_F(HandlesTest, DynamicRegistrationSameHook) {
 
     // Run it again - we should have added something to this hook.
     CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2));
     getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
     zero_results();
     getCalloutManager()->callCallouts(delta_index_, callout_handle_2);
@@ -670,7 +670,7 @@ TEST_F(HandlesTest, DynamicRegistrationSameHook) {
 
     // And a third time...
     CalloutHandle callout_handle_3(getCalloutManager());
-    callout_handle_3.setArgument("handle_num", static_cast<int>(3)); 
+    callout_handle_3.setArgument("handle_num", static_cast<int>(3));
     getCalloutManager()->callCallouts(alpha_index_, callout_handle_3);
     zero_results();
     getCalloutManager()->callCallouts(delta_index_, callout_handle_3);
@@ -694,7 +694,7 @@ TEST_F(HandlesTest, DynamicDeregistrationDifferentHook) {
 
     // Call the callouts on alpha
     CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1));
     getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
 
     zero_results();
@@ -707,7 +707,7 @@ TEST_F(HandlesTest, DynamicDeregistrationDifferentHook) {
     // The run of the callouts should have altered the callout list on the
     // first library for hook alpha, so call again to make sure.
     CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2));
     getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
 
     zero_results();
@@ -734,7 +734,7 @@ TEST_F(HandlesTest, DynamicDeregistrationSameHook) {
 
     // Call the callouts on alpha
     CalloutHandle callout_handle_1(getCalloutManager());
-    callout_handle_1.setArgument("handle_num", static_cast<int>(1)); 
+    callout_handle_1.setArgument("handle_num", static_cast<int>(1));
     getCalloutManager()->callCallouts(alpha_index_, callout_handle_1);
 
     zero_results();
@@ -745,7 +745,7 @@ TEST_F(HandlesTest, DynamicDeregistrationSameHook) {
     // The run of the callouts should have altered the callout list on the
     // first library for hook alpha, so call again to make sure.
     CalloutHandle callout_handle_2(getCalloutManager());
-    callout_handle_2.setArgument("handle_num", static_cast<int>(2)); 
+    callout_handle_2.setArgument("handle_num", static_cast<int>(2));
     getCalloutManager()->callCallouts(alpha_index_, callout_handle_2);
 
     zero_results();
diff --git a/src/lib/hooks/tests/hooks_manager_unittest.cc b/src/lib/hooks/tests/hooks_manager_unittest.cc
index c1a3600..c5dba60 100644
--- a/src/lib/hooks/tests/hooks_manager_unittest.cc
+++ b/src/lib/hooks/tests/hooks_manager_unittest.cc
@@ -82,21 +82,21 @@ public:
 
         // Perform the first calculation.
         handle->setArgument("data_1", d1);
-        HooksManager::callCallouts(lm_one_index_, *handle);
+        HooksManager::callCallouts(hookpt_one_index_, *handle);
         handle->getArgument(RESULT, result);
-        EXPECT_EQ(r1, result) << "lm_one" << COMMON_TEXT;
+        EXPECT_EQ(r1, result) << "hookpt_one" << COMMON_TEXT;
 
         // ... the second ...
         handle->setArgument("data_2", d2);
-        HooksManager::callCallouts(lm_two_index_, *handle);
+        HooksManager::callCallouts(hookpt_two_index_, *handle);
         handle->getArgument(RESULT, result);
-        EXPECT_EQ(r2, result) << "lm_two" << COMMON_TEXT;
+        EXPECT_EQ(r2, result) << "hookpt_two" << COMMON_TEXT;
 
         // ... and the third.
         handle->setArgument("data_3", d3);
-        HooksManager::callCallouts(lm_three_index_, *handle);
+        HooksManager::callCallouts(hookpt_three_index_, *handle);
         handle->getArgument(RESULT, result);
-        EXPECT_EQ(r3, result) << "lm_three" << COMMON_TEXT;
+        EXPECT_EQ(r3, result) << "hookpt_three" << COMMON_TEXT;
     }
 
 };
@@ -117,7 +117,7 @@ TEST_F(HooksManagerTest, LoadLibraries) {
     // Execute the callouts.  The first library implements the calculation.
     //
     // r3 = (7 * d1 - d2) * d3
-    // 
+    //
     // The last-loaded library implements the calculation
     //
     // r3 = (10 + d1) * d2 - d3
@@ -161,7 +161,7 @@ TEST_F(HooksManagerTest, LoadLibrariesWithError) {
     // Execute the callouts.  The first library implements the calculation.
     //
     // r3 = (7 * d1 - d2) * d3
-    // 
+    //
     // The last-loaded library implements the calculation
     //
     // r3 = (10 + d1) * d2 - d3
@@ -305,7 +305,7 @@ TEST_F(HooksManagerTest, ReloadLibrariesReverseOrder) {
     // Execute the callouts.  The first library implements the calculation.
     //
     // r3 = (7 * d1 - d2) * d3
-    // 
+    //
     // The last-loaded library implements the calculation
     //
     // r3 = (10 + d1) * d2 - d3
@@ -353,7 +353,7 @@ testPostCallout(CalloutHandle& handle) {
 
 }
 
-// The next test registers the pre and post- callouts above for hook lm_two,
+// The next test registers the pre and post- callouts above for hook hookpt_two,
 // and checks they are called.
 
 TEST_F(HooksManagerTest, PrePostCalloutTest) {
@@ -364,12 +364,12 @@ TEST_F(HooksManagerTest, PrePostCalloutTest) {
     EXPECT_TRUE(HooksManager::loadLibraries(library_names));
 
     // Load the pre- and post- callouts.
-    HooksManager::preCalloutsLibraryHandle().registerCallout("lm_two",
+    HooksManager::preCalloutsLibraryHandle().registerCallout("hookpt_two",
                                                              testPreCallout);
-    HooksManager::postCalloutsLibraryHandle().registerCallout("lm_two",
+    HooksManager::postCalloutsLibraryHandle().registerCallout("hookpt_two",
                                                               testPostCallout);
 
-    // Execute the callouts.  lm_two implements the calculation:
+    // Execute the callouts.  hookpt_two implements the calculation:
     //
     //  "result - data_2"
     //
@@ -380,7 +380,7 @@ TEST_F(HooksManagerTest, PrePostCalloutTest) {
     handle->setArgument("result", static_cast<int>(0));
     handle->setArgument("data_2", static_cast<int>(15));
 
-    HooksManager::callCallouts(lm_two_index_, *handle);
+    HooksManager::callCallouts(hookpt_two_index_, *handle);
 
     int result = 0;
     handle->getArgument("result", result);
@@ -394,7 +394,7 @@ TEST_F(HooksManagerTest, PrePostCalloutTest) {
     handle->setArgument("result", static_cast<int>(0));
     handle->setArgument("data_2", static_cast<int>(15));
 
-    HooksManager::callCallouts(lm_two_index_, *handle);
+    HooksManager::callCallouts(hookpt_two_index_, *handle);
 
     result = 0;
     handle->getArgument("result", result);
@@ -406,9 +406,9 @@ TEST_F(HooksManagerTest, PrePostCalloutTest) {
 
 TEST_F(HooksManagerTest, NoLibrariesCalloutsPresent) {
     // No callouts should be present on any hooks.
-    EXPECT_FALSE(HooksManager::calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(HooksManager::calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(HooksManager::calloutsPresent(lm_three_index_));
+    EXPECT_FALSE(HooksManager::calloutsPresent(hookpt_one_index_));
+    EXPECT_FALSE(HooksManager::calloutsPresent(hookpt_two_index_));
+    EXPECT_FALSE(HooksManager::calloutsPresent(hookpt_three_index_));
 }
 
 TEST_F(HooksManagerTest, NoLibrariesCallCallouts) {
diff --git a/src/lib/hooks/tests/library_manager_collection_unittest.cc b/src/lib/hooks/tests/library_manager_collection_unittest.cc
index 762d850..549142f 100644
--- a/src/lib/hooks/tests/library_manager_collection_unittest.cc
+++ b/src/lib/hooks/tests/library_manager_collection_unittest.cc
@@ -82,7 +82,7 @@ TEST_F(LibraryManagerCollectionTest, LoadLibraries) {
     // Execute the callouts.  The first library implements the calculation.
     //
     // r3 = (7 * d1 - d2) * d3
-    // 
+    //
     // The last-loaded library implements the calculation
     //
     // r3 = (10 + d1) * d2 - d3
@@ -135,7 +135,7 @@ TEST_F(LibraryManagerCollectionTest, LoadLibrariesWithError) {
     // Execute the callouts.  The first library implements the calculation.
     //
     // r3 = (7 * d1 - d2) * d3
-    // 
+    //
     // The last-loaded library implements the calculation
     //
     // r3 = (10 + d1) * d2 - d3
diff --git a/src/lib/hooks/tests/library_manager_unittest.cc b/src/lib/hooks/tests/library_manager_unittest.cc
index 0ddfbc4..c2f8cb7 100644
--- a/src/lib/hooks/tests/library_manager_unittest.cc
+++ b/src/lib/hooks/tests/library_manager_unittest.cc
@@ -89,7 +89,8 @@ public:
     /// @param r0...r3, d1..d3 Values and intermediate values expected.  They
     ///        are ordered so that the variables appear in the argument list in
     ///        the order they are used.  See HooksCommonTestClass::execute for
-    ///        a full description.
+    ///        a full description. (rN is used to indicate an expected result,
+    ///        dN is data to be passed to the calculation.)
     void executeCallCallouts(int r0, int d1, int r1, int d2, int r2, int d3,
                              int r3) {
         HooksCommonTestClass::executeCallCallouts(callout_manager_, r0, d1,
@@ -186,6 +187,22 @@ TEST_F(LibraryManagerTest, WrongVersion) {
     EXPECT_TRUE(lib_manager.closeLibrary());
 }
 
+// Check that the code handles the case of a library where the version function
+// throws an exception.
+
+TEST_F(LibraryManagerTest, VersionException) {
+    PublicLibraryManager lib_manager(std::string(FRAMEWORK_EXCEPTION_LIBRARY),
+                                     0, callout_manager_);
+    // Open should succeed.
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Version check should fail.
+    EXPECT_FALSE(lib_manager.checkVersion());
+
+    // Tidy up.
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
 // Tests that checkVersion() function succeeds in the case of a library with a
 // version function that returns the correct version number.
 
@@ -244,12 +261,12 @@ TEST_F(LibraryManagerTest, CheckLoadCalled) {
     // Load the standard callouts
     EXPECT_NO_THROW(lib_manager.registerStandardCallouts());
 
-    // Check that only context_create and lm_one have callouts registered.
+    // Check that only context_create and hookpt_one have callouts registered.
     EXPECT_TRUE(callout_manager_->calloutsPresent(
                 ServerHooks::CONTEXT_CREATE));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(hookpt_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_three_index_));
     EXPECT_FALSE(callout_manager_->calloutsPresent(
                  ServerHooks::CONTEXT_DESTROY));
 
@@ -257,9 +274,9 @@ TEST_F(LibraryManagerTest, CheckLoadCalled) {
     EXPECT_TRUE(lib_manager.runLoad());
     EXPECT_TRUE(callout_manager_->calloutsPresent(
                 ServerHooks::CONTEXT_CREATE));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(hookpt_one_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(hookpt_two_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(hookpt_three_index_));
     EXPECT_FALSE(callout_manager_->calloutsPresent(
                  ServerHooks::CONTEXT_DESTROY));
 
@@ -273,6 +290,23 @@ TEST_F(LibraryManagerTest, CheckLoadCalled) {
     EXPECT_TRUE(lib_manager.closeLibrary());
 }
 
+// Check handling of a "load" function that throws an exception
+
+TEST_F(LibraryManagerTest, CheckLoadException) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(FRAMEWORK_EXCEPTION_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Running the load function should fail.
+    EXPECT_FALSE(lib_manager.runLoad());
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
 // Check handling of a "load" function that returns an error.
 
 TEST_F(LibraryManagerTest, CheckLoadError) {
@@ -324,6 +358,23 @@ TEST_F(LibraryManagerTest, CheckUnloadError) {
     EXPECT_TRUE(lib_manager.closeLibrary());
 }
 
+// Unload function throws an exception.
+
+TEST_F(LibraryManagerTest, CheckUnloadException) {
+
+    // Load the only library, specifying the index of 0 as it's the only
+    // library.  This should load all callouts.
+    PublicLibraryManager lib_manager(std::string(FRAMEWORK_EXCEPTION_LIBRARY),
+                                     0, callout_manager_);
+    EXPECT_TRUE(lib_manager.openLibrary());
+
+    // Check that we detect that the unload function throws an exception.
+    EXPECT_FALSE(lib_manager.runUnload());
+
+    // Tidy up
+    EXPECT_TRUE(lib_manager.closeLibrary());
+}
+
 // Check that the case of the library's unload() function returning a
 // success is handled correcty.
 
@@ -367,33 +418,33 @@ TEST_F(LibraryManagerTest, LibUnload) {
     EXPECT_TRUE(lib_manager.checkVersion());
 
     // No callouts should be registered at the moment.
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_three_index_));
 
     // Load the single standard callout and check it is registered correctly.
     EXPECT_NO_THROW(lib_manager.registerStandardCallouts());
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(hookpt_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_three_index_));
 
     // Call the load function to load the other callouts.
     EXPECT_TRUE(lib_manager.runLoad());
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_TRUE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(hookpt_one_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(hookpt_two_index_));
+    EXPECT_TRUE(callout_manager_->calloutsPresent(hookpt_three_index_));
 
     // Unload the library and check that the callouts have been removed from
     // the CalloutManager.
     lib_manager.unloadLibrary();
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_three_index_));
 }
 
 // Now come the loadLibrary() tests that make use of all the methods tested
 // above.  These tests are really to make sure that the methods have been
-// tied toget correctly.
+// tied together correctly.
 
 // First test the basic error cases - no library, no version function, version
 // function returning an error.
@@ -437,9 +488,9 @@ TEST_F(LibraryManagerTest, LoadLibrary) {
     EXPECT_TRUE(lib_manager.unloadLibrary());
 
     // Check that the callouts have been removed from the callout manager.
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_one_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_two_index_));
-    EXPECT_FALSE(callout_manager_->calloutsPresent(lm_three_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_one_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_two_index_));
+    EXPECT_FALSE(callout_manager_->calloutsPresent(hookpt_three_index_));
 }
 
 // Now test for multiple libraries.  We'll load the full callout library
@@ -479,7 +530,7 @@ TEST_F(LibraryManagerTest, LoadMultipleLibraries) {
     // Execute the callouts.  The first library implements the calculation.
     //
     // r3 = (7 * d1 - d2) * d3
-    // 
+    //
     // The last-loaded library implements the calculation
     //
     // r3 = (10 + d1) * d2 - d3
diff --git a/src/lib/hooks/tests/load_callout_library.cc b/src/lib/hooks/tests/load_callout_library.cc
index b428597..ae9f470 100644
--- a/src/lib/hooks/tests/load_callout_library.cc
+++ b/src/lib/hooks/tests/load_callout_library.cc
@@ -20,9 +20,9 @@
 /// file are:
 ///
 /// - The "version" and "load" framework functions are supplied.  One "standard"
-///   callout is supplied ("lm_one") and two non-standard ones which are
-///   registered during the call to "load" on the hooks "lm_two" and
-///   "lm_three". 
+///   callout is supplied ("hookpt_one") and two non-standard ones which are
+///   registered during the call to "load" on the hooks "hookpt_two" and
+///   "hookpt_three".
 ///
 ///   All callouts do trivial calculations, the result of all being called in
 ///   sequence being
@@ -30,8 +30,8 @@
 ///   @f[ ((5 * data_1) + data_2) * data_3 @f]
 ///
 ///   ...where data_1, data_2 and data_3 are the values passed in arguments of
-///   the same name to the three callouts (data_1 passed to lm_one, data_2 to
-///   lm_two etc.) and the result is returned in the argument "result".
+///   the same name to the three callouts (data_1 passed to hookpt_one, data_2 to
+///   hookpt_two etc.) and the result is returned in the argument "result".
 
 #include <hooks/hooks.h>
 
@@ -54,7 +54,7 @@ context_create(CalloutHandle& handle) {
 // between callouts in the same library.)
 
 int
-lm_one(CalloutHandle& handle) {
+hookpt_one(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_1", data);
 
@@ -71,7 +71,7 @@ lm_one(CalloutHandle& handle) {
 // argument.
 
 static int
-lm_nonstandard_two(CalloutHandle& handle) {
+hook_nonstandard_two(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_2", data);
 
@@ -87,7 +87,7 @@ lm_nonstandard_two(CalloutHandle& handle) {
 // Final callout adds "data_3" to the result.
 
 static int
-lm_nonstandard_three(CalloutHandle& handle) {
+hook_nonstandard_three(CalloutHandle& handle) {
     int data;
     handle.getArgument("data_3", data);
 
@@ -109,8 +109,8 @@ version() {
 
 int load(LibraryHandle& handle) {
     // Register the non-standard functions
-    handle.registerCallout("lm_two", lm_nonstandard_two);
-    handle.registerCallout("lm_three", lm_nonstandard_three);
+    handle.registerCallout("hookpt_two", hook_nonstandard_two);
+    handle.registerCallout("hookpt_three", hook_nonstandard_three);
 
     return (0);
 }
diff --git a/src/lib/hooks/tests/test_libraries.h.in b/src/lib/hooks/tests/test_libraries.h.in
index 68ea4e9..8d9b932 100644
--- a/src/lib/hooks/tests/test_libraries.h.in
+++ b/src/lib/hooks/tests/test_libraries.h.in
@@ -20,7 +20,7 @@
 namespace {
 
 
-// Take carse of differences in DLL naming between operating systems.
+// Take care of differences in DLL naming between operating systems.
 
 #ifdef OS_BSD
 #define DLL_SUFFIX ".dylib"
@@ -45,6 +45,10 @@ static const char* BASIC_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libbcl"
 static const char* FULL_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libfcl"
                                           DLL_SUFFIX;
 
+// Library where the all framework functions throw an exception
+static const char* FRAMEWORK_EXCEPTION_LIBRARY = "@abs_builddir@/.libs/libfxl"
+                                                 DLL_SUFFIX;
+
 // Library where the version() function returns an incorrect result.
 static const char* INCORRECT_VERSION_LIBRARY = "@abs_builddir@/.libs/libivl"
                                                DLL_SUFFIX;
@@ -69,7 +73,6 @@ static const char* NO_VERSION_LIBRARY = "@abs_builddir@/.libs/libnvl"
 // Library where there is an unload() function.
 static const char* UNLOAD_CALLOUT_LIBRARY = "@abs_builddir@/.libs/libucl"
                                             DLL_SUFFIX;
-
 } // anonymous namespace
 
 



More information about the bind10-changes mailing list