Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
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 
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   
00156   
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