Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
MC: allow to pass env variables to the verified application
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Sun, 10 Jul 2022 22:08:30 +0000 (00:08 +0200)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Sun, 10 Jul 2022 22:22:11 +0000 (00:22 +0200)
docs/source/Configuring_SimGrid.rst
src/mc/api.cpp
src/mc/api.hpp
src/mc/explo/simgrid_mc.cpp

index f907c9d..4ea9206 100644 (file)
@@ -119,6 +119,7 @@ Existing Configuration Items
 - **model-check/reduction:** :ref:`cfg=model-check/reduction`
 - **model-check/replay:** :ref:`cfg=model-check/replay`
 - **model-check/send-determinism:** :ref:`cfg=model-check/send-determinism`
+- **model-check/setenv:** :ref:`cfg=model-check/setenv`
 - **model-check/termination:** :ref:`cfg=model-check/termination`
 - **model-check/timeout:** :ref:`cfg=model-check/timeout`
 - **model-check/visited:** :ref:`cfg=model-check/visited`
@@ -769,6 +770,15 @@ The ``model-check/communications-determinism`` and
 communication determinism mode of the model checker, which checks
 determinism properties of the communications of an application.
 
+.. _cfg=model-check/setenv:
+
+Passing environment variables
+.............................
+
+You can specify extra environment variables to be set in the verified application
+with ``model-check/setenv``. For example, you can preload a library as follows:
+``-cfg=model-check/setenv:LD_PRELOAD=toto;LD_LIBRARY_PATH=/tmp``.
+
 .. _options_mc_perf:
 
 Verification Performance Considerations
index 840ffef..7a8c8db 100644 (file)
@@ -30,12 +30,19 @@ XBT_LOG_EXTERNAL_CATEGORY(mc_global);
 
 namespace simgrid::mc {
 
-simgrid::mc::Exploration* Api::initialize(char** argv, simgrid::mc::ExplorationAlgorithm algo)
+simgrid::mc::Exploration* Api::initialize(char** argv, const std::unordered_map<std::string, std::string>& env,
+                                          simgrid::mc::ExplorationAlgorithm algo)
 {
-  session_ = std::make_unique<simgrid::mc::Session>([argv] {
+  session_ = std::make_unique<simgrid::mc::Session>([argv, &env] {
     int i = 1;
     while (argv[i] != nullptr && argv[i][0] == '-')
       i++;
+    for (auto const& kv : env) {
+      const char* key = kv.first.c_str();
+      const char* val = kv.second.c_str();
+      XBT_INFO("setenv '%s'='%s'", key, val);
+      setenv(key, val, 1);
+    }
     xbt_assert(argv[i] != nullptr,
                "Unable to find a binary to exec on the command line. Did you only pass config flags?");
     execvp(argv[i], argv + i);
index 88b2e0c..3edcb07 100644 (file)
@@ -53,7 +53,8 @@ public:
     return api;
   }
 
-  simgrid::mc::Exploration* initialize(char** argv, simgrid::mc::ExplorationAlgorithm algo);
+  simgrid::mc::Exploration* initialize(char** argv, const std::unordered_map<std::string, std::string>& env,
+                                       simgrid::mc::ExplorationAlgorithm algo);
 
   // ACTOR APIs
   std::vector<simgrid::mc::ActorInformation>& get_actors() const;
index afd997a..769c14c 100644 (file)
 #include "smpi/smpi.h"
 #endif
 
+#include <boost/tokenizer.hpp>
 #include <cstring>
 #include <memory>
 #include <unistd.h>
 
+static simgrid::config::Flag<std::string> _sg_mc_setenv{
+    "model-check/setenv", "Extra environment variables to pass to the child process (ex: 'AZE=aze;QWE=qwe').", "",
+    [](std::string_view value) {
+      xbt_assert(value.empty() || value.find('=', 0) != std::string_view::npos,
+                 "The 'model-check/setenv' parameter must be like 'AZE=aze', but it does not contain an equal sign.");
+    }};
+
 int main(int argc, char** argv)
 {
   xbt_assert(argc >= 2, "Missing arguments");
@@ -44,8 +52,25 @@ int main(int argc, char** argv)
   else
     algo = simgrid::mc::ExplorationAlgorithm::Liveness;
 
+  std::unordered_map<std::string, std::string> environment;
+  /** Setup the tokenizer that parses the string **/
+  using Tokenizer = boost::tokenizer<boost::char_separator<char>>;
+  boost::char_separator<char> semicol_sep(";");
+  boost::char_separator<char> equal_sep("=");
+  Tokenizer token_vars(_sg_mc_setenv.get(), semicol_sep); /* Iterate over all FOO=foo parts */
+  for (const auto& token : token_vars) {
+    std::vector<std::string> kv;
+    Tokenizer token_kv(token, equal_sep);
+    for (const auto& t : token_kv) /* Iterate over 'FOO' and then 'foo' in that 'FOO=foo' */
+      kv.push_back(t);
+    xbt_assert(kv.size() == 2, "Parse error on 'model-check/setenv' value %s. Does it contain an equal sign?",
+               token.c_str());
+    environment[kv[0]] = kv[1];
+  }
+
   int res      = SIMGRID_MC_EXIT_SUCCESS;
-  std::unique_ptr<simgrid::mc::Exploration> checker{simgrid::mc::Api::get().initialize(argv_copy.data(), algo)};
+  std::unique_ptr<simgrid::mc::Exploration> checker{
+      simgrid::mc::Api::get().initialize(argv_copy.data(), environment, algo)};
   try {
     checker->run();
   } catch (const simgrid::mc::DeadlockError&) {