[macOS] Crash with Signal 6 on double-clicking layout files with non-ASCII paths (missing exception handling in GuiApplication::event)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 72/100
Línea de trabajo
Start with src/lay/lay/layApplication.cc and compare the macOS QEvent::FileOpen handler with the protected calls in MainWindow::dropEvent and MainWindow::cm_open. Then inspect src/tl/tl/tlInternational.cc, including the Q_WS_MAC conditional. Done means Finder-launched files with non-ASCII paths no longer abort KLayout and failures show the existing error dialog; verify on macOS with Qt5/Qt6.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
Double-clicking a layout file (.gds, .oas, etc.) in macOS Finder crashes KLayout with Signal number: 6 (SIGABRT) if the file path contains non-ASCII characters (such as CJK characters, e.g. the default Microsoft OneDrive directory OneDrive-个人).
When the same file is dragged into an already running KLayout instance, KLayout does not crash; instead, it safely shows an error dialog:
Unable to open file: ... (errno=2)
Environment
- KLayout Version: 0.30.12 (and earlier versions on Qt5/Qt6)
- OS: macOS (Apple Silicon / arm64)
Crash Backtrace
Signal number: 6
Address: 0x18af2c5e8
Program Version: KLayout 0.30.12
Backtrace:
libklayout_lay.0.dylib _ZN3lay25enable_signal_handler_guiEb
libsystem_platform.dylib _sigtramp
libsystem_pthread.dylib pthread_kill
libsystem_c.dylib abort
libc++abi.dylib _ZN10__cxxabiv116__shim_type_infoD1Ev
libc++abi.dylib _ZSt14set_unexpectedPFvvE
libobjc.A.dylib _ZL15_objc_terminatev
libc++abi.dylib _ZSt11__terminatePFvvE
libc++abi.dylib _ZN10__cxxabiv1L13is_class_typeEPKNS_16__shim_type_infoE
libklayout_lay.0.dylib _ZN3lay10MainWindow21create_or_load_layoutEPKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPKN2db17LoadLayoutOptionsERS8_i
libklayout_lay.0.dylib _ZN3lay14GuiApplication5eventEP6QEvent
QtWidgets _ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent
QtWidgets _ZN12QApplication6notifyEP7QObjectP6QEvent
libklayout_lay.0.dylib _ZN3lay14GuiApplication9do_notifyEP7QObjectP6QEvent
QtCore _ZN16QCoreApplication15notifyInternal2EP7QObjectP6QEvent
QtGui _ZN22QGuiApplicationPrivate20processFileOpenEventEPN29QWindowSystemInterfacePrivate13FileOpenEventE
QtGui _ZN22QWindowSystemInterface19handleFileOpenEventERK7QString
libqcocoa.dylib qt_plugin_instance
AppKit -[NSApplication(NSAppleEventHandling) _openURLs:requestedBySourceApp:completionHandler:]
AppKit __69-[NSApplication(NSAppleEventHandling) _handleAEOpenDocumentsForURLs:]_block_invoke
AppKit __102-[NSApplication _reopenWindowsAsNecessaryIncludingRestorableState:withFullFidelity:completionHandler:]_block_invoke
AppKit -[NSApplication run]
...
Root Cause Analysis
There are two interrelated issues causing this bug:
1. Missing Exception Handling in GuiApplication::event for QEvent::FileOpen
In src/lay/lay/layApplication.cc:
bool
GuiApplication::event (QEvent *event)
{
#if defined(__APPLE__)
if (event->type() == QEvent::FileOpen) {
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
if (mp_mw)
{
const std::string tech = mp_mw->initial_technology();
const std::string file = tl::to_string (openEvent->file());
const int mode = 1; // open in new window
mp_mw->load_layout (file, tech, mode);
mp_mw->add_mru (file, tech);
}
}
#endif
return QApplication::event(event);
}
In MainWindow::dropEvent and MainWindow::cm_open, calls to load_layout are protected with BEGIN_PROTECTED ... END_PROTECTED.
In GuiApplication::event, however, mp_mw->load_layout(...) is called without BEGIN_PROTECTED or try...catch.
When load_layout fails for any reason (e.g. non-existent path, permission error, corrupted file), create_or_load_layout re-throws tl::Exception. The uncaught C++ exception escapes the Qt Cocoa plugin boundary into AppKit's Objective-C runloop (_openURLs:requestedBySourceApp:completionHandler:), triggering _objc_terminatev -> std::terminate() -> abort() -> SIGABRT (Signal 6).
2. Locale and Encoding Fallback on macOS GUI Launch
Why does load_layout fail with errno=2 (ENOENT) in the first place when files reside in paths with non-ASCII characters?
In src/tl/tl/tlInternational.cc:
void initialize_codecs ()
{
// determine encoder for system strings
#ifdef _WIN32
ms_system_codec = 0;
#elif defined(Q_WS_MAC)
ms_system_codec = QTextCodec::codecForName ("UTF-8");
#else
setlocale (LC_ALL, "");
ms_system_codec = QTextCodec::codecForName (nl_langinfo (CODESET));
if (! ms_system_codec) {
ms_system_codec = QTextCodec::codecForName ("Latin-1");
}
#endif
Q_WS_MACis obsolete and was removed in Qt 5 (Qt 5+ usesQ_OS_MACorQ_OS_MACOS). Therefore, the#elif defined(Q_WS_MAC)branch is never compiled under Qt 5 / Qt 6.- On macOS, applications launched from Finder (via LaunchServices) do not inherit
LANGorLC_*environment variables from the user shell. - When
setlocale(LC_ALL, "")runs withoutLANG/LC_ALLset,nl_langinfo(CODESET)returnsUS-ASCII. - As a result,
ms_system_codecis set toUS-ASCII. When converting the path withstring_to_system(source)(ortl::to_local), any non-ASCII character (such as个人in~/Library/CloudStorage/OneDrive-个人/...) is replaced with?or stripped, causing POSIXopen()/gzopen()to fail witherrno=2(ENOENT). - (When run directly from Terminal where
LANG=...UTF-8is present,nl_langinfo(CODESET)is UTF-8, which is why the command-line launch does not trigger this error).
Suggested Fix
- In
src/lay/lay/layApplication.cc, wrap theFileOpenhandler inBEGIN_PROTECTED ... END_PROTECTED:
if (event->type() == QEvent::FileOpen) {
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
if (mp_mw)
{
BEGIN_PROTECTED
const std::string tech = mp_mw->initial_technology();
const std::string file = tl::to_string (openEvent->file());
const int mode = 1; // open in new window
mp_mw->load_layout (file, tech, mode);
mp_mw->add_mru (file, tech);
END_PROTECTED
}
}
- In
src/tl/tl/tlInternational.cc, updateQ_WS_MACtoQ_OS_MAC:
#ifdef _WIN32
ms_system_codec = 0;
#elif defined(Q_OS_MAC)
ms_system_codec = QTextCodec::codecForName ("UTF-8");
#else
setlocale (LC_ALL, "");
ms_system_codec = QTextCodec::codecForName (nl_langinfo (CODESET));
if (! ms_system_codec) {
ms_system_codec = QTextCodec::codecForName ("Latin-1");
}
#endif
- Lenguaje dominante
- C++
- Estrellas
- 1.2k
- Forks
- 305
- Merge medio
- 3 d 2 h
- PR fusionados (30 d)
- 11
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de KLayout/klayout
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
KLayout/klayout#2554 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
KLayout/klayout#2412 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
DRC functions not working properly with clip in placePosiblemente ocupada @klayoutmatthias la tomó hoy. Abiertobug
KLayout/klayout#2553 · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 50/100
Los mantenedores suelen responder en 1 día
-
Deep DRC can miss violations when a cell has many shapesQuizá libre de nuevo Un pull request para esta issue se cerró sin fusionarse. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 52/100
KLayout/klayout#2546 · 5 comentarios ·
Los mantenedores suelen responder en 1 día
Todos los issues de KLayout/klayout
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
Integer underflow and buffer overrun in detail::count_rows on disconnected distance matricesAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 3 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
LaneDibello/Kotor-Patch-Manager#375 ·
Los mantenedores suelen responder en 2 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
Los mantenedores suelen responder en 1 día