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:
parent
25cf46036d
commit
72b7eb8332
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
19
test/emu/ovni/thread-crash.c
Normal file
19
test/emu/ovni/thread-crash.c
Normal 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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user