python accessing freed shared memory object (#1253)

* added a 'isValid' member in shared memory (also updated shm version) with default true, any access to shared memory() checks also for validity. any free will set this to false and then unmap shm. Any access to shm will then check validity in python.

* fixed tests for shm

* added tests in python as well

---------

Co-authored-by: Alice <alice.mazzoleni@psi.ch>
This commit is contained in:
2025-08-05 11:26:49 +02:00
committed by GitHub
parent f714aa22c5
commit f594826e95
11 changed files with 258 additions and 40 deletions

View File

@@ -10,7 +10,7 @@
namespace sls {
TEST_CASE("Default construction") {
static_assert(sizeof(CtbConfig) == ((18 + 32 + 64 + 5 + 8) * 20),
static_assert(sizeof(CtbConfig) == ((18 + 32 + 64 + 5 + 8) * 20 + 1),
"Size of CtbConfig does not match");
CtbConfig c;

View File

@@ -5,27 +5,35 @@
#include "catch.hpp"
#include "sls/string_utils.h"
#include <iostream>
namespace sls {
struct Data {
int x;
double y;
char mess[50];
bool isValid{true};
};
void freeShm(const int dindex, const int mIndex) {
SharedMemory<Data> shm(dindex, mIndex);
if (shm.exists()) {
shm.openSharedMemory(false);
shm()->isValid = false;
shm.removeSharedMemory();
}
}
constexpr int shm_id = 10;
TEST_CASE("Create SharedMemory read and write", "[detector]") {
const char *env_p = std::getenv("SLSDETNAME");
std::string env_name = env_p ? ("_" + std::string(env_p)) : "";
SharedMemory<Data> shm(shm_id, -1);
if (shm.exists()) {
shm.removeSharedMemory();
}
shm.createSharedMemory();
const char *env_p = std::getenv("SLSDETNAME");
std::string env_name = env_p ? ("_" + std::string(env_p)) : "";
CHECK(shm.getName() == std::string("/slsDetectorPackage_detector_") +
std::to_string(shm_id) + env_name);
@@ -44,16 +52,19 @@ TEST_CASE("Create SharedMemory read and write", "[detector]") {
}
TEST_CASE("Open existing SharedMemory and read", "[detector]") {
{
SharedMemory<double> shm(shm_id, -1);
SharedMemory<Data> shm(shm_id, -1);
if (shm.exists()) {
shm.removeSharedMemory();
}
shm.createSharedMemory();
*shm() = 5.3;
shm()->x = 3;
shm()->y = 5.9;
}
SharedMemory<double> shm2(shm_id, -1);
SharedMemory<Data> shm2(shm_id, -1);
shm2.openSharedMemory(true);
CHECK(*shm2() == 5.3);
CHECK(shm2()->y == 5.9);
shm2.removeSharedMemory();
}
@@ -61,8 +72,8 @@ TEST_CASE("Open existing SharedMemory and read", "[detector]") {
TEST_CASE("Creating a second shared memory with the same name throws",
"[detector]") {
SharedMemory<double> shm0(shm_id, -1);
SharedMemory<double> shm1(shm_id, -1);
SharedMemory<Data> shm0(shm_id, -1);
SharedMemory<Data> shm1(shm_id, -1);
shm0.createSharedMemory();
CHECK_THROWS(shm1.createSharedMemory());
@@ -120,19 +131,18 @@ TEST_CASE("Create several shared memories", "[detector]") {
std::string env_name = env_p ? ("_" + std::string(env_p)) : "";
constexpr int N = 5;
std::vector<SharedMemory<int>> v;
std::vector<SharedMemory<Data>> v;
v.reserve(N);
for (int i = 0; i != N; ++i) {
std::cout << "i:" << i << std::endl;
v.emplace_back(shm_id + i, -1);
CHECK(v[i].exists() == false);
v[i].createSharedMemory();
*v[i]() = i;
CHECK(*v[i]() == i);
v[i]()->x = i;
CHECK(v[i]()->x == i);
}
for (int i = 0; i != N; ++i) {
CHECK(*v[i]() == i);
CHECK(v[i]()->x == i);
CHECK(v[i].getName() == std::string("/slsDetectorPackage_detector_") +
std::to_string(i + shm_id) + env_name);
}
@@ -147,7 +157,7 @@ TEST_CASE("Create create a shared memory with a tag") {
const char *env_p = std::getenv("SLSDETNAME");
std::string env_name = env_p ? ("_" + std::string(env_p)) : "";
SharedMemory<int> shm(0, -1, "ctbdacs");
SharedMemory<Data> shm(0, -1, "ctbdacs");
REQUIRE(shm.getName() ==
"/slsDetectorPackage_detector_0" + env_name + "_ctbdacs");
}
@@ -162,7 +172,7 @@ TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set") {
unsetenv(SHM_ENV_NAME);
setenv(SHM_ENV_NAME, "myprefix", 1);
SharedMemory<int> shm(0, -1, "ctbdacs");
SharedMemory<Data> shm(0, -1, "ctbdacs");
REQUIRE(shm.getName() == "/slsDetectorPackage_detector_0_myprefix_ctbdacs");
// Clean up after us
@@ -172,15 +182,14 @@ TEST_CASE("Create create a shared memory with a tag when SLSDETNAME is set") {
setenv(SHM_ENV_NAME, old_slsdetname.c_str(), 1);
}
TEST_CASE("map int64 to int32 throws") {
SharedMemory<int32_t> shm(shm_id, -1);
TEST_CASE("Access to already freed shm object", "[detector]") {
SharedMemory<Data> shm(shm_id, -1);
shm.createSharedMemory();
*shm() = 7;
shm()->x = 10;
SharedMemory<int64_t> shm2(shm_id, -1);
REQUIRE_THROWS(shm2.openSharedMemory(true));
shm.removeSharedMemory();
freeShm(shm_id, -1);
CHECK(shm.exists() == false);
REQUIRE_THROWS(shm()); // trying to access should throw
}
} // namespace sls