test_malloc_wrappers.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2010, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 #include <gtest/gtest.h>
00036 
00037 #include "rosrt/malloc_wrappers.h"
00038 #include "ros/atomic.h"
00039 #include <ros/time.h>
00040 #include <ros/console.h>
00041 
00042 #include <boost/thread.hpp>
00043 
00044 #if __unix__ && !APPLE
00045 #include <dlfcn.h>
00046 #endif
00047 
00048 using namespace rosrt;
00049 using namespace ros;
00050 
00051 void allocateThread(const atomic<bool>& done)
00052 {
00053   while (!done.load())
00054   {
00055     void* mem = malloc(500);
00056     free(mem);
00057     ros::WallDuration(0.001).sleep();
00058   }
00059 }
00060 
00061 TEST(MallocWrappers, statsMainThread)
00062 {
00063   atomic<bool> done(false);
00064   boost::thread t(boost::bind(allocateThread, boost::ref(done)));
00065 
00066   resetThreadAllocInfo();
00067 
00068   for (uint32_t i = 1; i <= 1000; ++i)
00069   {
00070     void* mem = malloc(500);
00071     free(mem);
00072     ros::WallDuration(0.001).sleep();
00073 
00074     AllocInfo info = getThreadAllocInfo();
00075     ASSERT_EQ(info.mallocs, i);
00076     ASSERT_EQ(info.frees, i);
00077     ASSERT_EQ(info.total_ops, i * 2);
00078   }
00079 
00080   done.store(true);
00081   t.join();
00082 }
00083 
00084 void statsThread(atomic<bool>& failed)
00085 {
00086   resetThreadAllocInfo();
00087 
00088   for (uint32_t i = 1; i <= 1000; ++i)
00089   {
00090     void* mem = malloc(500);
00091     free(mem);
00092     ros::WallDuration(0.001).sleep();
00093 
00094     AllocInfo info = getThreadAllocInfo();
00095     if (info.mallocs != i)
00096     {
00097       ROS_ERROR_STREAM("mallocs is " << info.mallocs << " should be " << i);
00098       failed.store(true);
00099       return;
00100     }
00101 
00102     if (info.frees != i)
00103     {
00104       ROS_ERROR_STREAM("mallocs is " << info.frees << " should be " << i);
00105       failed.store(true);
00106       return;
00107     }
00108   }
00109 }
00110 
00111 TEST(MallocWrappers, statsNewThread)
00112 {
00113   atomic<bool> failed(false);
00114   boost::thread t(boost::bind(statsThread, boost::ref(failed)));
00115   t.join();
00116 
00117   ASSERT_FALSE(failed.load());
00118 }
00119 
00120 // TODO: once we have a low-level dynamic library wrapper, use it and allow testing on non-unix platforms
00121 #if __unix__ && !APPLE
00122 TEST(MallocWrappers, sharedObjectDynamicallyOpened)
00123 {
00124   void* handle = dlopen("libtest_malloc_wrappers_so.so", RTLD_LAZY|RTLD_GLOBAL);
00125   ASSERT_TRUE(handle);
00126   void*(*alloc_func)(size_t) = (void*(*)(size_t))dlsym(handle, "myTestMalloc");
00127   ASSERT_TRUE(handle);
00128   void(*free_func)(void*) = (void(*)(void*))dlsym(handle, "myTestFree");
00129   ASSERT_TRUE(free_func);
00130 
00131   resetThreadAllocInfo();
00132   void* mem = alloc_func(500);
00133   free_func(mem);
00134 
00135   AllocInfo info = getThreadAllocInfo();
00136   ASSERT_EQ(info.mallocs, 1U);
00137   ASSERT_EQ(info.frees, 1U);
00138 
00139   dlclose(handle);
00140 }
00141 #endif
00142 
00143 void doBreakOnMalloc()
00144 {
00145   setThreadBreakOnAllocOrFree(true);
00146   void* mem = malloc(500);
00147   mem = 0;
00148   setThreadBreakOnAllocOrFree(false);
00149 }
00150 
00151 TEST(MallocWrappersDeathTest, breakOnAllocFree)
00152 {
00153   resetThreadAllocInfo();
00154 
00155   // TODO: Re-enable once ROS 1.1 goes out with the updated version of gtest
00156   //ASSERT_DEATH_IF_SUPPORTED(doBreakOnMalloc(), "Issuing break due to break_on_alloc_or_free being set");
00157 }
00158 
00159 int main(int argc, char** argv)
00160 {
00161   testing::InitGoogleTest(&argc, argv);
00162   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
00163   return RUN_ALL_TESTS();
00164 }
00165 


rosrt
Author(s): Josh Faust
autogenerated on Sat Jun 8 2019 20:43:39