mirror of https://github.com/KLayout/klayout.git
Fixes a potential crash during breakpoint handling
This fixes the following problem: * Set a breakpoint in a PCell code * Change the PCell, breakpoint gets triggered * While debugger is in breakpoint, close the view with the PCell To prevent any kind of interference, events are now disabled during breakpoint mode. As this interferes with the help dialog, you cannot open the help dialog either.
This commit is contained in:
parent
12d09687cd
commit
acbbd92194
|
|
@ -94,16 +94,23 @@ namespace lay
|
|||
// --------------------------------------------------------------------------------
|
||||
// Exception handlers
|
||||
|
||||
static void close_transaction ()
|
||||
{
|
||||
// if any transaction is pending (this may happen when an operation threw an exception)
|
||||
// close transactions.
|
||||
// NOTE: don't do this in breakpoint mode as we do not want to interfere with things happening outside
|
||||
if (lay::MainWindow::instance () && lay::MainWindow::instance ()->manager ().transacting () &&
|
||||
!(lay::MacroEditorDialog::instance () && lay::MacroEditorDialog::instance ()->in_breakpoint ())) {
|
||||
lay::MainWindow::instance ()->manager ().commit ();
|
||||
}
|
||||
}
|
||||
|
||||
static void ui_exception_handler_tl (const tl::Exception &ex, QWidget *parent)
|
||||
{
|
||||
// Prevents severe side effects if there are pending deferred methods
|
||||
tl::NoDeferredMethods silent;
|
||||
|
||||
// if any transaction is pending (this may happen when an operation threw an exception)
|
||||
// close transactions.
|
||||
if (lay::MainWindow::instance () && lay::MainWindow::instance ()->manager ().transacting ()) {
|
||||
lay::MainWindow::instance ()->manager ().commit ();
|
||||
}
|
||||
close_transaction ();
|
||||
|
||||
const tl::ExitException *gsi_exit = dynamic_cast <const tl::ExitException *> (&ex);
|
||||
const tl::BreakException *gsi_break = dynamic_cast <const tl::BreakException *> (&ex);
|
||||
|
|
@ -155,13 +162,9 @@ static void ui_exception_handler_std (const std::exception &ex, QWidget *parent)
|
|||
// Prevents severe side effects if there are pending deferred methods
|
||||
tl::NoDeferredMethods silent;
|
||||
|
||||
// if any transaction is pending (this may happen when an operation threw an exception)
|
||||
// close transactions.
|
||||
if (lay::MainWindow::instance () && lay::MainWindow::instance ()->manager ().transacting ()) {
|
||||
lay::MainWindow::instance ()->manager ().commit ();
|
||||
}
|
||||
close_transaction ();
|
||||
|
||||
tl::error << ex.what ();
|
||||
tl::error << ex.what ();
|
||||
if (! parent) {
|
||||
parent = QApplication::activeWindow () ? QApplication::activeWindow () : lay::MainWindow::instance ();
|
||||
}
|
||||
|
|
@ -173,11 +176,7 @@ static void ui_exception_handler_def (QWidget *parent)
|
|||
// Prevents severe side effects if there are pending deferred methods
|
||||
tl::NoDeferredMethods silent;
|
||||
|
||||
// if any transaction is pending (this may happen when an operation threw an exception)
|
||||
// close transactions.
|
||||
if (lay::MainWindow::instance () && lay::MainWindow::instance ()->manager ().transacting ()) {
|
||||
lay::MainWindow::instance ()->manager ().commit ();
|
||||
}
|
||||
close_transaction ();
|
||||
|
||||
if (! parent) {
|
||||
parent = QApplication::activeWindow () ? QApplication::activeWindow () : lay::MainWindow::instance ();
|
||||
|
|
|
|||
|
|
@ -1511,26 +1511,25 @@ MacroEditorDialog::eventFilter (QObject *obj, QEvent *event)
|
|||
|
||||
if (lay::BusySection::is_busy ()) {
|
||||
|
||||
#if 0
|
||||
if (dynamic_cast <QInputEvent *> (event) != 0 || dynamic_cast <QPaintEvent *> (event) != 0) {
|
||||
if (m_in_breakpoint && (dynamic_cast <QInputEvent *> (event) != 0 || dynamic_cast <QPaintEvent *> (event) != 0)) {
|
||||
|
||||
// In breakpoint or execution mode and while processing the events inside the debugger,
|
||||
// In breakpoint mode and while processing the events inside the debugger,
|
||||
// ignore all input or paint events targeted to widgets which are not children of this or the assistant dialog.
|
||||
// Ignoring the paint event is required because otherwise a repaint action would be triggered on a layout which
|
||||
// is potentially unstable or inconsistent.
|
||||
// We nevertheless allow events send to a HelpDialog or ProgressWidget since those are vital for the application's
|
||||
// functionality and are known not to cause any interference.
|
||||
QObject *rec = obj;
|
||||
while (rec && (rec != this && !dynamic_cast<lay::HelpDialog *> (rec) && !dynamic_cast<lay::ProgressWidget *> (rec))) {
|
||||
while (rec && rec != this) {
|
||||
rec = rec->parent ();
|
||||
}
|
||||
if (! rec) {
|
||||
// TODO: reschedule the paint events (?)
|
||||
event->accept ();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -2267,19 +2266,35 @@ END_PROTECTED
|
|||
}
|
||||
|
||||
void
|
||||
MacroEditorDialog::help_requested(const QString &s)
|
||||
MacroEditorDialog::help_requested (const QString &s)
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
// Do not allow modal popups in breakpoint mode - this would interfere with
|
||||
// event filtering during breakpoint execution
|
||||
if (m_in_breakpoint) {
|
||||
throw tl::Exception (tl::to_string (tr ("The help function is not available in breakpoint mode.")));
|
||||
}
|
||||
|
||||
lay::MainWindow::instance ()->show_assistant_topic (tl::to_string (s));
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorDialog::help_button_clicked()
|
||||
MacroEditorDialog::help_button_clicked ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
// Do not allow modal popups in breakpoint mode - this would interfere with
|
||||
// event filtering during breakpoint execution
|
||||
if (m_in_breakpoint) {
|
||||
throw tl::Exception (tl::to_string (tr ("The help function is not available in breakpoint mode.")));
|
||||
}
|
||||
|
||||
lay::MainWindow::instance ()->show_assistant_url ("int:/code/index.xml");
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
MacroEditorDialog::add_button_clicked()
|
||||
MacroEditorDialog::add_button_clicked ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
new_macro ();
|
||||
|
|
@ -2287,7 +2302,7 @@ END_PROTECTED
|
|||
}
|
||||
|
||||
lym::Macro *
|
||||
MacroEditorDialog::new_macro()
|
||||
MacroEditorDialog::new_macro ()
|
||||
{
|
||||
ensure_writeable_collection_selected ();
|
||||
|
||||
|
|
@ -3451,6 +3466,11 @@ MacroEditorDialog::leave_breakpoint_mode ()
|
|||
mp_current_interpreter = 0;
|
||||
do_update_ui_to_run_mode ();
|
||||
set_exec_point (0, -1, -1);
|
||||
|
||||
// refresh UI that might have been spoiled because we filter events
|
||||
if (lay::MainWindow::instance ()) {
|
||||
lay::MainWindow::instance ()->update ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -166,6 +166,14 @@ public:
|
|||
return m_in_exec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true while the macro IDE is in breakpoint mode
|
||||
*/
|
||||
bool in_breakpoint () const
|
||||
{
|
||||
return m_in_breakpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects the current category in the tree view
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue