+ xbt_assert(result->file_name);
+ xbt_assert(result->start_rw);
+ xbt_assert(result->start_exec);
+}
+
+/************************************* Take Snapshot ************************************/
+/****************************************************************************************/
+
+/** \brief Checks whether the variable is in scope for a given IP.
+ *
+ * A variable may be defined only from a given value of IP.
+ *
+ * \param var Variable description
+ * \param frame Scope description
+ * \param ip Instruction pointer
+ * \return true if the variable is valid
+ * */
+static bool mc_valid_variable(dw_variable_t var, dw_frame_t frame, const void* ip) {
+ // The variable is not yet valid:
+ if((const void*)((const char*) frame->low_pc + var->start_scope) > ip)
+ return false;
+ else
+ return true;
+}
+
+static void mc_fill_local_variables_values(mc_stack_frame_t stack_frame, dw_frame_t scope, xbt_dynar_t result) {
+ void* ip = (void*) stack_frame->ip;
+ if(ip < scope->low_pc || ip>= scope->high_pc)
+ return;
+
+ unsigned cursor = 0;
+ dw_variable_t current_variable;
+ xbt_dynar_foreach(scope->variables, cursor, current_variable){
+
+ if(!mc_valid_variable(current_variable, stack_frame->frame, (void*) stack_frame->ip))
+ continue;
+
+ int region_type;
+ if((long)stack_frame->ip > (long)mc_libsimgrid_info->start_exec)
+ region_type = 1;
+ else
+ region_type = 2;
+
+ local_variable_t new_var = xbt_new0(s_local_variable_t, 1);
+ new_var->subprogram = stack_frame->frame;
+ new_var->ip = stack_frame->ip;
+ new_var->name = xbt_strdup(current_variable->name);
+ new_var->type = current_variable->type;
+ new_var->region= region_type;
+
+ /* if(current_variable->address!=NULL) {
+ new_var->address = current_variable->address;
+ } else */
+ if(current_variable->locations.size != 0){
+ new_var->address = (void*) mc_dwarf_resolve_locations(¤t_variable->locations,
+ current_variable->object_info,
+ &(stack_frame->unw_cursor), (void*)stack_frame->frame_base, NULL);
+ }
+
+ xbt_dynar_push(result, &new_var);
+ }
+
+ // Recursive processing of nested scopes:
+ dw_frame_t nested_scope = NULL;
+ xbt_dynar_foreach(scope->scopes, cursor, nested_scope) {
+ mc_fill_local_variables_values(stack_frame, nested_scope, result);
+ }
+}
+
+static xbt_dynar_t MC_get_local_variables_values(xbt_dynar_t stack_frames){
+
+ unsigned cursor1 = 0;
+ mc_stack_frame_t stack_frame;
+ xbt_dynar_t variables = xbt_dynar_new(sizeof(local_variable_t), local_variable_free_voidp);
+
+ xbt_dynar_foreach(stack_frames,cursor1,stack_frame) {
+ mc_fill_local_variables_values(stack_frame, stack_frame->frame, variables);
+ }
+
+ return variables;
+}
+
+static void MC_stack_frame_free_voipd(void *s){
+ mc_stack_frame_t stack_frame = *(mc_stack_frame_t*)s;
+ if(stack_frame) {
+ xbt_free(stack_frame->frame_name);
+ xbt_free(stack_frame);
+ }
+}
+
+static xbt_dynar_t MC_unwind_stack_frames(void *stack_context) {
+ xbt_dynar_t result = xbt_dynar_new(sizeof(mc_stack_frame_t), MC_stack_frame_free_voipd);
+
+ unw_cursor_t c;
+
+ // TODO, check condition check (unw_init_local==0 means end of frame)
+ if(unw_init_local(&c, (unw_context_t *)stack_context)!=0) {
+
+ xbt_die("Could not initialize stack unwinding");
+
+ } else while(1) {
+
+ mc_stack_frame_t stack_frame = xbt_new(s_mc_stack_frame_t, 1);
+ xbt_dynar_push(result, &stack_frame);
+
+ stack_frame->unw_cursor = c;
+
+ unw_word_t ip, sp;
+
+ unw_get_reg(&c, UNW_REG_IP, &ip);
+ unw_get_reg(&c, UNW_REG_SP, &sp);
+
+ stack_frame->ip = ip;
+ stack_frame->sp = sp;
+
+ // TODO, use real addresses in frame_t instead of fixing it here
+
+ dw_frame_t frame = MC_find_function_by_ip((void*) ip);
+ stack_frame->frame = frame;
+
+ if(frame) {
+ stack_frame->frame_name = xbt_strdup(frame->name);
+ stack_frame->frame_base = (unw_word_t)mc_find_frame_base(frame, frame->object_info, &c);
+ } else {
+ stack_frame->frame_base = 0;
+ stack_frame->frame_name = NULL;
+ }
+
+ /* Stop before context switch with maestro */
+ if(frame!=NULL && frame->name!=NULL && !strcmp(frame->name, "smx_ctx_sysv_wrapper"))
+ break;
+
+ int ret = ret = unw_step(&c);
+ if(ret==0) {
+ xbt_die("Unexpected end of stack.");
+ } else if(ret<0) {
+ xbt_die("Error while unwinding stack.");
+ }
+ }
+
+ if(xbt_dynar_length(result) == 0){
+ XBT_INFO("unw_init_local failed");
+ xbt_abort();
+ }
+
+ return result;
+};
+
+static xbt_dynar_t MC_take_snapshot_stacks(mc_snapshot_t *snapshot, void *heap){
+
+ xbt_dynar_t res = xbt_dynar_new(sizeof(s_mc_snapshot_stack_t), MC_snapshot_stack_free_voidp);
+
+ unsigned int cursor = 0;
+ stack_region_t current_stack;