Fix some on error memory leaks in vvp.
This patch modifies the vvp main code to cleanup if there was an error compiling the input file. There are still a few issues, but this takes care of most of them.
This commit is contained in:
parent
07ee2e7dff
commit
3868334f5c
67
vvp/main.cc
67
vvp/main.cc
|
|
@ -192,6 +192,41 @@ void set_delay_selection(const char* sel)
|
|||
delete[] sel;
|
||||
}
|
||||
|
||||
static void final_cleanup()
|
||||
{
|
||||
/*
|
||||
* We only need to cleanup the memory if we are checking with valgrind.
|
||||
*/
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
/* Clean up the file name table. */
|
||||
for (vector<const char*>::iterator cur = file_names.begin();
|
||||
cur != file_names.end() ; cur++) {
|
||||
delete[] *cur;
|
||||
}
|
||||
/* Clear the static result buffer. */
|
||||
(void)need_result_buf(0, RBUF_DEL);
|
||||
codespace_delete();
|
||||
root_table_delete();
|
||||
def_table_delete();
|
||||
vpi_mcd_delete();
|
||||
dec_str_delete();
|
||||
modpath_delete();
|
||||
vpi_handle_delete();
|
||||
udp_defns_delete();
|
||||
island_delete();
|
||||
signal_pool_delete();
|
||||
vvp_net_pool_delete();
|
||||
ufunc_pool_delete();
|
||||
#endif
|
||||
/*
|
||||
* Unload the VPI modules. This is essential for MinGW, to ensure
|
||||
* dump files are flushed before the main process terminates, as
|
||||
* the DLL termination code is called after all remaining open
|
||||
* files are automatically closed.
|
||||
*/
|
||||
load_module_delete();
|
||||
}
|
||||
|
||||
unsigned module_cnt = 0;
|
||||
const char*module_tab[64];
|
||||
|
||||
|
|
@ -385,6 +420,7 @@ int main(int argc, char*argv[])
|
|||
if (compile_errors > 0) {
|
||||
vpi_mcd_printf(1, "%s: Program not runnable, %u errors.\n",
|
||||
design_path, compile_errors);
|
||||
final_cleanup();
|
||||
return compile_errors;
|
||||
}
|
||||
|
||||
|
|
@ -463,36 +499,7 @@ int main(int argc, char*argv[])
|
|||
count_gen_events, count_gen_pool());
|
||||
}
|
||||
|
||||
/*
|
||||
* We only need to cleanup the memory if we are checking with valgrind.
|
||||
*/
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
/* Clean up the memory. */
|
||||
for (vector<const char*>::iterator cur = file_names.begin();
|
||||
cur != file_names.end() ; cur++) {
|
||||
delete[] *cur;
|
||||
}
|
||||
(void)need_result_buf(0, RBUF_DEL);
|
||||
codespace_delete();
|
||||
root_table_delete();
|
||||
def_table_delete();
|
||||
vpi_mcd_delete();
|
||||
dec_str_delete();
|
||||
modpath_delete();
|
||||
vpi_handle_delete();
|
||||
udp_defns_delete();
|
||||
island_delete();
|
||||
signal_pool_delete();
|
||||
vvp_net_pool_delete();
|
||||
ufunc_pool_delete();
|
||||
#endif
|
||||
/*
|
||||
* Unload the VPI modules. This is essential for MinGW, to ensure
|
||||
* dump files are flushed before the main process terminates, as
|
||||
* the DLL termination code is called after all remaining open
|
||||
* files are automatically closed.
|
||||
*/
|
||||
load_module_delete();
|
||||
final_cleanup();
|
||||
|
||||
return vvp_return_value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -713,6 +713,18 @@ void print_vpi_call_errors()
|
|||
free(vpi_call_error_lst);
|
||||
}
|
||||
|
||||
static void cleanup_vpi_call_args(unsigned argc, vpiHandle*argv)
|
||||
{
|
||||
#ifdef CHECK_WITH_VALGRIND
|
||||
if (argc) {
|
||||
struct __vpiSysTaskCall*obj = new struct __vpiSysTaskCall;
|
||||
obj->nargs = argc;
|
||||
obj->args = argv;
|
||||
vpi_call_delete(&obj->base);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* A vpi_call is actually built up into a vpiSysTaskCall VPI object
|
||||
* that refers back to the vpiUserSystf VPI object that is the
|
||||
|
|
@ -736,6 +748,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
|
|||
struct __vpiUserSystf*defn = vpip_find_systf(name);
|
||||
if (defn == 0) {
|
||||
add_vpi_call_error(VPI_CALL_NO_DEF, name, file_idx, lineno);
|
||||
cleanup_vpi_call_args(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -744,6 +757,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
|
|||
if (vwid != 0 || fnet != 0) {
|
||||
add_vpi_call_error(VPI_CALL_TASK_AS_FUNC, name, file_idx,
|
||||
lineno);
|
||||
cleanup_vpi_call_args(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
assert(vbit == 0);
|
||||
|
|
@ -754,6 +768,7 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
|
|||
if (func_as_task_err) {
|
||||
add_vpi_call_error(VPI_CALL_FUNC_AS_TASK,
|
||||
name, file_idx, lineno);
|
||||
cleanup_vpi_call_args(argc, argv);
|
||||
return 0;
|
||||
} else if (func_as_task_warn) {
|
||||
add_vpi_call_error(VPI_CALL_FUNC_AS_TASK_WARN,
|
||||
|
|
@ -818,6 +833,8 @@ vpiHandle vpip_build_vpi_call(const char*name, unsigned vbit, int vwid,
|
|||
void vpi_call_delete(vpiHandle item)
|
||||
{
|
||||
struct __vpiSysTaskCall*obj = (struct __vpiSysTaskCall *) item;
|
||||
/* The object can be NULL if there was an error. */
|
||||
if (!obj) return;
|
||||
for (unsigned arg = 0; arg < obj->nargs; arg += 1) {
|
||||
switch (obj->args[arg]->vpi_type->type_code) {
|
||||
case vpiConstant:
|
||||
|
|
|
|||
Loading…
Reference in New Issue