A memory leak occurs when command 'step' is followed by 'quit'

without having reached the final TSTOP.
New function DCtran_step_quit() removes the leak.
This commit is contained in:
Holger Vogt 2026-03-21 19:57:16 +01:00
parent 2d3e032a3f
commit aab3371f36
4 changed files with 38 additions and 26 deletions

View File

@ -517,7 +517,7 @@ ft_bpcheck(struct plot *runplot, int iteration)
if ((howmanysteps > 0) && (--howmanysteps == 0)) {
if (steps > 1)
fprintf(cp_err, "Stopped after %d steps.\n", steps);
fprintf(cp_out, "Note: Stopped after %d steps.\n", steps);
return (FALSE);
}
@ -694,3 +694,14 @@ printcond(struct dbcomm *d, FILE *fp)
}
}
}
/* just check if we are in 'step' mode */
bool
ft_stepcheck(void)
{
if ((steps > 0) && (howmanysteps == 0)) {
return (TRUE);
}
return (FALSE);
}

View File

@ -35,6 +35,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
extern void line_free_x(struct card *deck, bool recurse);
extern INPmodel *modtab;
extern NGHASHPTR modtabhash;
extern int DCtran_step_quit(CKTcircuit* ckt);
#ifdef SHARED_MODULE
extern void exec_controls(wordlist *newcontrols);
@ -219,6 +220,10 @@ com_remcirc(wordlist *wl)
EVTunsetup(ft_curckt->ci_ckt);
#endif
/* remove remnants of run after incomplete transient sim with 'step' */
if (ft_curckt->ci_ckt)
DCtran_step_quit(ft_curckt->ci_ckt);
if_cktfree(ft_curckt->ci_ckt, ft_curckt->ci_symtab);
for (v = ft_curckt->ci_vars; v; v = next) {
next = v->va_next;

View File

@ -26,9 +26,10 @@ Modified: 1999 Paolo Nenzi - 2000 AlansFixes
extern void ft_checkkids(void);
/* breakpoint.c */
/* breakp.c */
extern bool ft_bpcheck(struct plot *runplot, int iteration);
extern bool ft_stepcheck(void);
extern void dbfree(struct dbcomm *db);
extern void dbfree1(struct dbcomm *db);
@ -173,29 +174,6 @@ extern struct dvec *ft_evaluate(struct pnode *node);
/* ftesopt.c */
extern struct variable *ft_getstat(struct circ *, char *);
/* ginterface.c
extern bool gi_init();
extern bool gi_endpause;
extern bool gi_rottext;
extern int gi_fntheight;
extern int gi_fntwidth;
extern int gi_maxx;
extern int gi_maxy;
extern int gi_nolst;
extern int gi_nocolors;
extern int gi_package;
extern void gi_arc();
extern void gi_clearscreen();
extern void gi_close();
extern void gi_drawline();
extern void gi_redraw();
extern void gi_setcolor();
extern void gi_resetcolor();
extern void gi_setlinestyle();
extern void gi_text();
extern void gi_update();
*/
/* graf.c */
@ -385,6 +363,5 @@ extern struct dvec* copycut(struct dvec* ov, struct dvec* newscalevec, int istar
extern bool ft_intrpt;
extern bool ft_setflag;
/* error.c */
#endif

View File

@ -969,3 +969,22 @@ chkStep:
}
/* NOTREACHED */
}
/* If we have a 'step' command, and then 'quit' before reaching the final time,
remove the run plot memory. */
int
DCtran_step_quit(CKTcircuit* ckt) {
if (!ckt || !ckt->CKTcurJob) /* nothing to delete */
return 0;
if (ckt->CKTcurJob->JOBtype != 4) /* only tran sim */
return 0;
if (!ft_stepcheck()) /* only after 'step' */
return 0;
TRANan* job = (TRANan*)ckt->CKTcurJob;
if (!job->TRANplot) /* already done */
return 0;
SPfrontEnd->OUTendPlot(job->TRANplot);
job->TRANplot = NULL;
return(OK);
}