Fix SIGSEGV in -dnull extraction/DEF read: guard Tk_RestrictEvents with TxTkConsole

The Tk_RestrictEvents() calls added to extraction (ExtSubtree.c), CIF/GDS
hierarchy generation (CIFhier.c) and DEF read (defRead.c) are guarded by
`if (SigInterruptOnSigIO != -1)`, intended to skip them in batch mode.

That check is insufficient for `magic -dnull -noconsole`: this mode is not
"batch mode" (SigInterruptOnSigIO == 0), so the guard passes, but magicdnull
never initializes the Tk package. Calling into Tk with a NULL stubs table
segfaults. It is reliably fatal on aarch64 (Pointer Authentication faults the
bad indirect call) while x86_64 often survives it. This breaks headless
extraction/LVS flows (e.g. SAK / LibreLane / open_pdks regression).

Guard these call sites with TxTkConsole (RuntimeFlags & MAIN_TK_CONSOLE)
instead, which is true only when a Tk console is actually present, and add the
missing `#include "utils/main.h"` where needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Harald Pretl 2026-07-06 11:47:12 +08:00
parent dcff2f64b8
commit 3a1d63b856
3 changed files with 8 additions and 6 deletions

View File

@ -40,6 +40,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "drc/drc.h"
#include "graphics/graphics.h"
#include "textio/textio.h"
#include "utils/main.h"
#include "utils/undo.h"
#include "utils/malloc.h"
#include "utils/signals.h"
@ -732,7 +733,7 @@ CIFGenSubcells(
Tk_RestrictProc *oldProc;
ClientData oldArg;
if (SigInterruptOnSigIO != -1) /* Check for batch mode */
if (TxTkConsole) /* only when a Tk console exists (never in -dnull) */
oldProc = Tk_RestrictEvents(RestrictInputProc, (ClientData)NULL, &oldArg);
#endif /* MAGIC_NO_TK */
#endif /* MAGIC_WRAPPER */
@ -888,7 +889,7 @@ CIFGenSubcells(
#ifdef MAGIC_WRAPPER
#ifndef MAGIC_NO_TK
/* Restore full event access */
if (SigInterruptOnSigIO != -1) /* Check for batch mode */
if (TxTkConsole) /* only when a Tk console exists (never in -dnull) */
Tk_RestrictEvents(oldProc, oldArg, &oldArg);
#endif /* MAGIC_NO_TK */
#endif /* MAGIC_WRAPPER */

View File

@ -42,6 +42,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "database/database.h"
#include "utils/malloc.h"
#include "textio/textio.h"
#include "utils/main.h"
#include "debug/debug.h"
#include "extract/extract.h"
#include "extract/extractInt.h"
@ -190,7 +191,7 @@ extSubtree(parentUse, reg, f)
Tk_RestrictProc *oldProc;
ClientData oldArg;
if (SigInterruptOnSigIO != -1) /* Check for batch mode */
if (TxTkConsole) /* only when a Tk console exists (never in -dnull) */
oldProc = Tk_RestrictEvents(RestrictInputProc, (ClientData)NULL, &oldArg);
#endif /* MAGIC_NO_TK */
#endif /* MAGIC_WRAPPER */
@ -389,7 +390,7 @@ done:
#ifdef MAGIC_WRAPPER
#ifndef MAGIC_NO_TK
/* Restore full event access */
if (SigInterruptOnSigIO != -1) /* Check for batch mode */
if (TxTkConsole) /* only when a Tk console exists (never in -dnull) */
Tk_RestrictEvents(oldProc, oldArg, &oldArg);
#endif /* MAGIC_NO_TK */
#endif /* MAGIC_WRAPPER */

View File

@ -2536,7 +2536,7 @@ DefRead(
* corrupt the database during DEF reads.
*/
if (SigInterruptOnSigIO != -1) /* Check for batch mode */
if (TxTkConsole) /* only when a Tk console exists (never in -dnull) */
oldProc = Tk_RestrictEvents(RestrictInputProc, (ClientData)NULL, &oldArg);
#endif /* MAGIC_NO_TK */
#endif /* MAGIC_WRAPPER */
@ -2764,7 +2764,7 @@ DefRead(
#ifdef MAGIC_WRAPPER
#ifndef MAGIC_NO_TK
/* Restore full event access */
if (SigInterruptOnSigIO != -1) /* Check for batch mode */
if (TxTkConsole) /* only when a Tk console exists (never in -dnull) */
Tk_RestrictEvents(oldProc, oldArg, &oldArg);
#endif /* MAGIC_NO_TK */
#endif /* MAGIC_WRAPPER */