Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] Test if the stack-cleaner has any effect
authorGabriel Corona <gabriel.corona@loria.fr>
Mon, 24 Nov 2014 15:03:10 +0000 (16:03 +0100)
committerGabriel Corona <gabriel.corona@loria.fr>
Tue, 25 Nov 2014 09:16:58 +0000 (10:16 +0100)
In order to test this:

 * we compile the same test program with and without the stack cleaner
   (`-fstack-cleaner`, `-fno-stack-cleaner`);

 * in this program, we move random bytes in the stack;

 * we expect the stack-cleaner to zero them out.

This test in only used if the configure stack-cleaner is detected to
support the `-fstack-cleaner` CLI option (it is the stack-cleaner
compiler wrapper).

CMakeLists.txt
buildtools/Cmake/AddTests.cmake
examples/msg/mc/CMakeLists.txt
examples/msg/mc/bugged1_liveness.c
examples/msg/mc/bugged1_liveness_stack_cleaner [new file with mode: 0755]

index a97eb96..80bc299 100644 (file)
@@ -10,6 +10,9 @@ endif()
 
 enable_language(CXX)
 
+INCLUDE(CheckCCompilerFlag)
+CHECK_C_COMPILER_FLAG(-fstack-cleaner HAVE_C_STACK_CLEANER)
+
 if (APPLE) #MAC
   set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
   set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
index 297b631..1343003 100644 (file)
@@ -117,6 +117,14 @@ ENDIF()
       ADD_TESH(mc-bugged1-liveness-ucontext-sparse  --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged1_liveness_sparse.tesh)
       ADD_TESH(mc-bugged1-liveness-visited-ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged1_liveness_visited.tesh)
       ADD_TESH(mc-bugged1-liveness-visited-ucontext-sparse --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged1_liveness_visited_sparse.tesh)
+    if(HAVE_C_STACK_CLEANER)
+      # This test checks if the stack cleaner is makign a difference:
+      add_test(mc-bugged1-liveness-stack-cleaner
+        ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/bugged1_liveness_stack_cleaner
+        ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/
+        ${CMAKE_BINARY_DIR}/examples/msg/mc/
+        )
+    endif()
     ENDIF()
   ENDIF()
 
index 483500c..5516685 100644 (file)
@@ -17,7 +17,20 @@ if(HAVE_MC)
   target_link_libraries(bugged3     simgrid )
   target_link_libraries(electric_fence     simgrid )
   target_link_libraries(bugged1_liveness     simgrid )
-  target_link_libraries(bugged2_liveness     simgrid )
+    target_link_libraries(bugged2_liveness     simgrid )
+
+  if(HAVE_C_STACK_CLEANER)
+    add_executable(bugged1_liveness_cleaner_on     bugged1_liveness.c )
+    add_executable(bugged1_liveness_cleaner_off     bugged1_liveness.c )
+
+    target_link_libraries(bugged1_liveness_cleaner_on     simgrid )
+    target_link_libraries(bugged1_liveness_cleaner_off     simgrid )
+
+    set_target_properties(bugged1_liveness_cleaner_on
+      PROPERTIES COMPILE_FLAGS "-DGARBAGE_STACK -fstack-cleaner")
+    set_target_properties(bugged1_liveness_cleaner_off
+      PROPERTIES COMPILE_FLAGS "-DGARBAGE_STACK -fno-stack-cleaner")
+  endif()
 
 endif()
 
index 09d3746..5143623 100644 (file)
 /* LTL property checked : G(r->F(cs)); (r=request of CS, cs=CS ok)            */
 /******************************************************************************/
 
+#ifdef GARBAGE_STACK
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#endif
+
 #include "msg/msg.h"
 #include "mc/mc.h"
 #include "xbt/automaton.h"
@@ -28,6 +34,16 @@ int predCS(){
   return cs;
 }
 
+#ifdef GARBAGE_STACK
+/** Do not use a clean stack */
+static void garbage_stack(void) {
+  const size_t size = 256;
+  int fd = open("/dev/urandom", O_RDONLY);
+  char foo[size];
+  read(fd, foo, size);
+  close(fd);
+}
+#endif
 
 int coordinator(int argc, char *argv[])
 {
@@ -84,7 +100,7 @@ int client(int argc, char *argv[])
 
   char *my_mailbox = xbt_strdup(argv[1]);
   msg_task_t grant = NULL, release = NULL;
-    
+
   while(1){
     XBT_INFO("Ask the request");
     MSG_task_send(MSG_task_create("request", 0, 1000, my_mailbox), "coordinator");
@@ -130,6 +146,17 @@ int client(int argc, char *argv[])
   return 0;
 }
 
+static int raw_client(int argc, char *argv[])
+{
+#ifdef GARBAGE_STACK
+  // At this point the stack of the callee (client) is probably filled with
+  // zeros and unitialized variables will contain 0. This call will place
+  // random byes in the stack of the callee:
+  garbage_stack();
+#endif
+  return client(argc, argv);
+}
+
 int main(int argc, char *argv[])
 {
 
@@ -146,7 +173,7 @@ int main(int argc, char *argv[])
   
   MSG_create_environment(platform_file);
   MSG_function_register("coordinator", coordinator);
-  MSG_function_register("client", client);
+  MSG_function_register("client", raw_client);
   MSG_launch_application(application_file);
   MSG_main();
 
diff --git a/examples/msg/mc/bugged1_liveness_stack_cleaner b/examples/msg/mc/bugged1_liveness_stack_cleaner
new file mode 100755 (executable)
index 0000000..2f372b6
--- /dev/null
@@ -0,0 +1,59 @@
+#!/bin/sh
+# Run the same test compiled with -fstack-cleaner / f-no-stack-cleaner
+# and compare the output.
+
+srcdir="$1"
+bindir="$2"
+
+cd "$srcdir"
+
+die() {
+  echo "$@" >&2
+  exit 1
+}
+
+assert() {
+  if ! eval "$1"; then
+    die "Assertion failed: $@"
+  fi
+}
+
+# If we don't have timeout, fake it:
+if ! which timeout > /dev/null; then
+  timeout() {
+    shift
+    "$@"
+  }
+fi
+
+run() {
+  state=$1
+  shift
+  timeout 30s ${bindir:=.}/bugged1_liveness_cleaner_$state \
+    ${srcdir:=.}/../../platforms/platform.xml \
+    ${srcdir:=.}/deploy_bugged1_liveness.xml \
+    --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" \
+    --cfg=contexts/factory:ucontext \
+    --cfg=contexts/stack_size:256
+  assert 'test $? = 134'
+}
+
+get_states() {
+  echo "$1" | grep "Expanded pairs = " | sed "s/^.*Expanded pairs = //" | head -n1
+}
+
+RES_ON="$(run on 2>&1 1>/dev/null)"
+RES_OFF="$(run off 2>&1 1>/dev/null)"
+
+STATES_ON=$(get_states "$RES_ON")
+STATES_OFF=$(get_states "$RES_OFF")
+
+# Both runs finished:
+assert 'test -n "$STATES_ON"'
+assert 'test -n "$STATES_OFF"'
+
+# We expect 21 visited pairs with the stack cleaner:
+assert 'test "$STATES_ON" = 21'
+
+# We expect more states without the stack cleaner:
+assert 'test "$STATES_ON" -lt "$STATES_OFF"'