| 560 | } |
| 561 | |
| 562 | void MIBreakpointController::createFromDebugger(const Value& miBkpt) |
| 563 | { |
| 564 | const QString type = miBkpt[QStringLiteral("type")].literal(); |
| 565 | Breakpoint::BreakpointKind gdbKind; |
| 566 | if (type == QLatin1String("breakpoint") || type == QLatin1String("catchpoint")) { |
| 567 | gdbKind = Breakpoint::CodeBreakpoint; |
| 568 | } else if (type == QLatin1String("watchpoint") || type == QLatin1String("hw watchpoint")) { |
| 569 | gdbKind = Breakpoint::WriteBreakpoint; |
| 570 | } else if (type == QLatin1String("read watchpoint")) { |
| 571 | gdbKind = Breakpoint::ReadBreakpoint; |
| 572 | } else if (type == QLatin1String("acc watchpoint")) { |
| 573 | gdbKind = Breakpoint::AccessBreakpoint; |
| 574 | } else { |
| 575 | qCWarning(DEBUGGERCOMMON) << "Unknown breakpoint type " << type; |
| 576 | return; |
| 577 | } |
| 578 | |
| 579 | // During debugger startup, we want to avoid creating duplicate breakpoints when the same breakpoint |
| 580 | // appears both in our model and in a init file e.g. .gdbinit |
| 581 | BreakpointModel* model = breakpointModel(); |
| 582 | const int numRows = model->rowCount(); |
| 583 | for (int row = 0; row < numRows; ++row) { |
| 584 | BreakpointDataPtr breakpoint = m_breakpoints.at(row); |
| 585 | const bool breakpointSent = breakpoint->debuggerId >= 0 || breakpoint->sent != 0; |
| 586 | if (breakpointSent && !m_deleteDuplicateBreakpoints) |
| 587 | continue; |
| 588 | |
| 589 | Breakpoint* modelBreakpoint = model->breakpoint(row); |
| 590 | if (modelBreakpoint->kind() != gdbKind) |
| 591 | continue; |
| 592 | |
| 593 | if (gdbKind == Breakpoint::CodeBreakpoint) { |
| 594 | bool sameLocation = false; |
| 595 | |
| 596 | if (const auto actualLocation = ActualBreakpointLocation{miBkpt}) { |
| 597 | sameLocation = actualLocation.line() == modelBreakpoint->line() |
| 598 | && actualLocation.filePath() |
| 599 | == modelBreakpoint->url().url(QUrl::PreferLocalFile | QUrl::StripTrailingSlash); |
| 600 | } |
| 601 | |
| 602 | if (!sameLocation && miBkpt.hasField(QStringLiteral("original-location"))) { |
| 603 | const QString location = miBkpt[QStringLiteral("original-location")].literal(); |
| 604 | if (location == modelBreakpoint->location()) { |
| 605 | sameLocation = true; |
| 606 | } else { |
| 607 | QRegExp rx(QStringLiteral("^(.+):(\\d+)$")); |
| 608 | if (rx.indexIn(location) != -1 && |
| 609 | Utils::unquoteExpression(rx.cap(1)) == modelBreakpoint->url().url(QUrl::PreferLocalFile | QUrl::StripTrailingSlash) && |
| 610 | rx.cap(2).toInt() - 1 == modelBreakpoint->line()) { |
| 611 | sameLocation = true; |
| 612 | } |
| 613 | } |
| 614 | } |
| 615 | |
| 616 | if (!sameLocation && miBkpt.hasField(QStringLiteral("what")) && miBkpt[QStringLiteral("what")].literal() == QLatin1String("exception throw")) { |
| 617 | if (modelBreakpoint->expression() == QLatin1String("catch throw") || |
| 618 | modelBreakpoint->expression() == QLatin1String("exception throw")) { |
| 619 | sameLocation = true; |
nothing calls this directly
no test coverage detected