Mark the finalization of streams

The emulator will now check that all threads are properly finalyzed by
calling ovni_thread_free(), as required by the specification. For now
only a warning is issued, which is enough to determine the cause of
potential emulator panics.

The ovni model is now always enabled.
This commit is contained in:
Rodrigo Arias 2023-11-10 18:07:07 +01:00
parent 25cf46036d
commit 72b7eb8332
5 changed files with 55 additions and 1 deletions

View File

@ -118,7 +118,27 @@ static const struct model_thread_spec th_spec = {
int int
model_ovni_probe(struct emu *emu) model_ovni_probe(struct emu *emu)
{ {
return model_version_probe(&model_ovni, emu); int ret = model_version_probe(&model_ovni, emu);
if (ret < 0) {
err("model_version_probe failed for ovni model");
return -1;
}
/* Ensure all threads finished by setting the 'ovni.finished' flag,
* otherwise the trace can be inconsistent */
struct system *sys = &emu->system;
for (struct thread *t = sys->threads; t; t = t->gnext) {
if (t->meta == NULL)
continue;
if (json_object_dotget_number(t->meta, "ovni.finished") == 0)
warn("incomplete stream: %s", t->id);
}
/* The ovni model is always enabled */
return 1;
} }
int int

View File

@ -458,6 +458,9 @@ thread_load_metadata(struct thread *thread, JSON_Object *meta)
return -1; return -1;
} }
if (json_object_dotget_number(meta, "ovni.finished") != 1)
warn("thread didn't finish properly: %s", thread->id);
thread->meta = meta; thread->meta = meta;
return 0; return 0;

View File

@ -571,6 +571,17 @@ ovni_thread_free(void)
if (!rthread.ready) if (!rthread.ready)
die("thread not initialized"); die("thread not initialized");
JSON_Object *meta = json_value_get_object(rthread.meta);
if (meta == NULL)
die("json_value_get_object failed");
/* Mark it finished so we can detect partial streams */
if (json_object_dotset_number(meta, "ovni.finished", 1) != 0)
die("json_object_dotset_string failed");
thread_metadata_store();
free(rthread.evbuf); free(rthread.evbuf);
} }

View File

@ -20,3 +20,4 @@ test_emu(tracedir-subdir.c MP DRIVER "tracedir-subdir.driver.sh")
test_emu(empty-stream.c SHOULD_FAIL REGEX "model_ovni_finish: thread .* is not dead") test_emu(empty-stream.c SHOULD_FAIL REGEX "model_ovni_finish: thread .* is not dead")
test_emu(require.c SHOULD_FAIL REGEX "unsupported ovni model version (want 666.66.6, have .*)") test_emu(require.c SHOULD_FAIL REGEX "unsupported ovni model version (want 666.66.6, have .*)")
test_emu(no-require.c REGEX "loading trace in compatibility mode") test_emu(no-require.c REGEX "loading trace in compatibility mode")
test_emu(thread-crash.c SHOULD_FAIL REGEX "incomplete stream")

View File

@ -0,0 +1,19 @@
/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC)
* SPDX-License-Identifier: GPL-3.0-or-later */
#include <ovni.h>
#include "instr.h"
/* Emulate a crash in one thread by not calling ovni_thread_free(). We need to
* call ovni_proc_fini() otherwise the metadata won't appear */
int
main(void)
{
instr_start(0, 1);
ovni_flush();
ovni_proc_fini();
return 0;
}