#include "mc_unw.h"
#include "mc_snapshot.h"
#include "mc_ignore.h"
-
-#include "simix/smx_private.h"
+#include "mc_smx.h"
+#include "mc_server.h"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_process, mc,
"MC process information");
&process->heap_address, std_heap_var->address, sizeof(struct mdesc*),
MC_PROCESS_INDEX_DISABLED);
- process->smx_process_infos = mc_smx_process_info_list_new();
- process->smx_old_process_infos = mc_smx_process_info_list_new();
+ process->smx_process_infos = MC_smx_process_info_list_new();
+ process->smx_old_process_infos = MC_smx_process_info_list_new();
process->checkpoint_ignore = MC_checkpoint_ignore_new();
void MC_process_refresh_malloc_info(mc_process_t process)
{
assert(!MC_process_is_self(process));
- if (!process->cache_flags & MC_PROCESS_CACHE_FLAG_HEAP)
+ if (!(process->cache_flags & MC_PROCESS_CACHE_FLAG_HEAP))
MC_process_refresh_heap(process);
// Refresh process->heapinfo:
- size_t malloc_info_bytesize = process->heap->heaplimit * sizeof(malloc_info);
+ size_t malloc_info_bytesize =
+ (process->heap->heaplimit + 1) * sizeof(malloc_info);
xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
- process->heap_info = (malloc_info*) realloc(process->heap_info,
- malloc_info_bytesize);
+ process->heap_info = realloc(process->heap_info, malloc_info_bytesize);
mmalloc_set_current_heap(heap);
MC_process_read(process, MC_ADDRESS_SPACE_READ_FLAGS_NONE,
MC_PROCESS_INDEX_DISABLED);
}
-/** Load the remote swag of processes into a dynar
- *
- * @param process MCed process
- * @param target Local dynar (to be filled with copies of `s_smx_process_t`)
- * @param remote_swag Address of the process SWAG in the remote list
- */
-static void MC_process_refresh_simix_process_list(
- mc_process_t process,
- xbt_dynar_t target, xbt_swag_t remote_swag)
-{
- // swag = REMOTE(*simix_global->process_list)
- s_xbt_swag_t swag;
- MC_process_read(process, MC_PROCESS_NO_FLAG, &swag, remote_swag, sizeof(swag),
- MC_PROCESS_INDEX_ANY);
-
- smx_process_t p;
- xbt_dynar_reset(target);
-
- int i = 0;
- for (p = swag.head; p; ++i) {
-
- s_mc_smx_process_info_t info;
- info.address = p;
- MC_process_read(process, MC_PROCESS_NO_FLAG,
- &info.copy, p, sizeof(info.copy), MC_PROCESS_INDEX_ANY);
- xbt_dynar_push(target, &info);
-
- // Lookup next process address:
- p = xbt_swag_getNext(&info.copy, swag.offset);
- }
- assert(i == swag.count);
-}
-
-void MC_process_refresh_simix_processes(mc_process_t process)
-{
- if (process->cache_flags & MC_PROCESS_CACHE_FLAG_SIMIX_PROCESSES)
- return;
-
- xbt_mheap_t heap = mmalloc_set_current_heap(mc_heap);
-
- // TODO, avoid to reload `&simix_global`, `simix_global`, `*simix_global`
-
- // simix_global_p = REMOTE(simix_global);
- smx_global_t simix_global_p;
- MC_process_read_variable(process, "simix_global", &simix_global_p, sizeof(simix_global_p));
-
- // simix_global = REMOTE(*simix_global)
- s_smx_global_t simix_global;
- MC_process_read(process, MC_PROCESS_NO_FLAG, &simix_global, simix_global_p, sizeof(simix_global),
- MC_PROCESS_INDEX_ANY);
-
- MC_process_refresh_simix_process_list(
- process, process->smx_process_infos, simix_global.process_list);
- MC_process_refresh_simix_process_list(
- process, process->smx_old_process_infos, simix_global.process_to_destroy);
-
- process->cache_flags |= MC_PROCESS_CACHE_FLAG_SIMIX_PROCESSES;
- mmalloc_set_current_heap(heap);
-}
-
#define SO_RE "\\.so[\\.0-9]*$"
#define VERSION_RE "-[\\.0-9]*$"
dw_variable_t var = MC_process_find_variable_by_name(process, name);
if (!var->address)
xbt_die("No simple location for this variable");
+ if (!var->type->full_type)
+ xbt_die("Partial type for %s, cannot check size", name);
+ if (var->type->full_type->byte_size != size)
+ xbt_die("Unexpected size for %s (expected %zi, was %zi)",
+ name, size, (size_t) var->type->full_type->byte_size);
MC_process_read(process, MC_PROCESS_NO_FLAG, target, var->address, size,
MC_PROCESS_INDEX_ANY);
}
+char* MC_process_read_string(mc_process_t process, void* address)
+{
+ if (!address)
+ return NULL;
+ if (MC_process_is_self(process))
+ return strdup((char*) address);
+
+ size_t len = 128;
+ char* res = malloc(len);
+ off_t off = 0;
+
+ while (1) {
+ ssize_t c = pread(process->memory_file, res + off, len - off, (off_t) address + off);
+ if (c == -1) {
+ if (errno == EINTR)
+ continue;
+ else
+ xbt_die("Could not read from from remote process");
+ }
+ if (c==0)
+ xbt_die("Could not read string from remote process");
+
+ void* p = memchr(res + off, '\0', c);
+ if (p)
+ return res;
+
+ off += c;
+ if (off == len) {
+ len *= 2;
+ res = realloc(res, len);
+ }
+ }
+}
+
// ***** Memory access
int MC_process_vm_open(pid_t pid, int flags)
}
}
+const void* MC_process_read_simple(mc_process_t process,
+ void* local, const void* remote, size_t len)
+{
+ e_adress_space_read_flags_t flags = MC_PROCESS_NO_FLAG;
+ int index = MC_PROCESS_INDEX_ANY;
+ MC_process_read(process, flags, local, remote, len, index);
+ return local;
+}
+
+const void* MC_process_read_dynar_element(mc_process_t process,
+ void* local, const void* remote_dynar, size_t i, size_t len)
+{
+ s_xbt_dynar_t d;
+ MC_process_read_simple(process, &d, remote_dynar, sizeof(d));
+ if (i >= d.used)
+ xbt_die("Out of bound index %zi/%zi", i, d.used);
+ if (len != d.elmsize)
+ xbt_die("Bad size in MC_process_read_dynar_element");
+ MC_process_read_simple(process, local, xbt_dynar_get_ptr(&d, i), len);
+ return local;
+}
+
void MC_process_write(mc_process_t process, const void* local, void* remote, size_t len)
{
if (MC_process_is_self(process)) {
}
}
+unsigned long MC_process_read_dynar_length(mc_process_t process, const void* remote_dynar)
+{
+ if (!remote_dynar)
+ return 0;
+ unsigned long res;
+ MC_process_read_simple(process, &res,
+ &((xbt_dynar_t)remote_dynar)->used, sizeof(res));
+ return res;
+}
+
static pthread_once_t zero_buffer_flag = PTHREAD_ONCE_INIT;
static const void* zero_buffer;
static const int zero_buffer_size = 10 * 4096;
}
}
-/** Get the issuer of a simcall (`req->issuer`)
- *
- * In split-process mode, it does the black magic necessary to get an address
- * of a (shallow) copy of the data structure the issuer SIMIX process in the local
- * address space.
- *
- * @param process the MCed process
- * @param req the simcall (copied in the local process)
- */
-smx_process_t MC_process_get_issuer(mc_process_t process, smx_simcall_t req)
-{
- if (MC_process_is_self(&mc_model_checker->process))
- return req->issuer;
-
- MC_process_refresh_simix_processes(process);
-
- // This is the address of the smx_process in the MCed process:
- void* address = req->issuer;
-
- unsigned i;
- mc_smx_process_info_t p;
-
- xbt_dynar_foreach_ptr(process->smx_process_infos, i, p)
- if (p->address == address)
- return &p->copy;
- xbt_dynar_foreach_ptr(process->smx_old_process_infos, i, p)
- if (p->address == address)
- return &p->copy;
-
- xbt_die("Issuer not found");
-}
-
void MC_simcall_handle(smx_simcall_t req, int value)
{
if (MC_process_is_self(&mc_model_checker->process)) {
return;
}
- MC_process_refresh_simix_processes(&mc_model_checker->process);
-
unsigned i;
mc_smx_process_info_t pi = NULL;
xbt_dynar_foreach_ptr(mc_model_checker->process.smx_process_infos, i, pi) {
- smx_process_t p = (smx_process_t) pi->address;
if (req == &pi->copy.simcall) {
- smx_simcall_t real_req = &p->simcall;
- // TODO, use a remote call
- SIMIX_simcall_handle(real_req, value);
+ MC_server_simcall_handle(&mc_model_checker->process, pi->copy.pid, value);
return;
}
}
- // Check (remove afterwards):
- xbt_dynar_foreach_ptr(mc_model_checker->process.smx_process_infos, i, pi) {
- smx_process_t p = (smx_process_t) pi->address;
- if (req == &p->simcall)
- xbt_die("The real simcall was passed. We expected the local copy.");
- }
-
xbt_die("Could not find the request");
}
-
-void mc_smx_process_info_clear(mc_smx_process_info_t p)
-{
- // Nothing yet
-}