diff --git a/NEWS.md b/NEWS.md index 74534ec1..d0554791 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,8 @@ Red Panda C++ Version 2.10 - fix: If buttons in the options dialog / compiler / compiler set page is pressed, they won't release. - enhancement: Confirm before remove a compiler set. - enhancement: If there is "cppreference.chm" or "cppreference-%locale_name%.chm"(like cppreference-zh_CN.chm) in the redpanda C++'s app folder, open it instead of the cppreference website. + - enhancement: Use lldb-mi as the debugger. + - enhancement: Set lldb-mi as the debugger program for clang, when finding compiler set in folders. Red Panda C++ Version 2.9 diff --git a/RedPandaIDE/debugger.cpp b/RedPandaIDE/debugger.cpp index 8c8028e7..e98436e0 100644 --- a/RedPandaIDE/debugger.cpp +++ b/RedPandaIDE/debugger.cpp @@ -35,6 +35,7 @@ Debugger::Debugger(QObject *parent) : QObject(parent), mForceUTF8(false), + mDebuggerType(DebuggerType::GDB), mLastLoadtime(0), mProjectLastLoadtime(0) { @@ -84,6 +85,10 @@ bool Debugger::start(int compilerSetIndex, const QString& inferior, const QStrin return false; } setForceUTF8(CompilerInfoManager::forceUTF8InDebugger(compilerSet->compilerType())); + if (compilerSet->debugger().endsWith(LLDB_MI_PROGRAM)) + setDebuggerType(DebuggerType::LLDB_MI); + else + setDebuggerType(DebuggerType::GDB); mExecuting = true; QString debuggerPath = compilerSet->debugger(); //QFile debuggerProgram(debuggerPath); @@ -507,7 +512,14 @@ void Debugger::refreshWatchVars() { if (mExecuting) { sendAllWatchVarsToDebugger(); - sendCommand("-var-update"," --all-values *"); + if (mDebuggerType==DebuggerType::LLDB_MI) { + for (PWatchVar var:mWatchModel->watchVars()) { + if (!var->name.isEmpty()) + sendCommand("-var-update",QString(" --all-values %1").arg(var->name)); + } + } else { + sendCommand("-var-update"," --all-values *"); + } } } @@ -518,6 +530,16 @@ void Debugger::fetchVarChildren(const QString &varName) } } +DebuggerType Debugger::debuggerType() const +{ + return mDebuggerType; +} + +void Debugger::setDebuggerType(DebuggerType newDebuggerType) +{ + mDebuggerType = newDebuggerType; +} + bool Debugger::forceUTF8() const { return mForceUTF8; @@ -606,10 +628,17 @@ void Debugger::sendBreakpointCommand(PBreakpoint breakpoint) } QString filename = breakpoint->filename; filename.replace('\\','/'); - sendCommand("-break-insert", - QString("%1 --source \"%2\" --line %3") - .arg(condition,filename) - .arg(breakpoint->line)); + if (debuggerType()==DebuggerType::LLDB_MI) { + sendCommand("-break-insert", + QString("%1 \"%2:%3\"") + .arg(condition, filename) + .arg(breakpoint->line)); + } else { + // sendCommand("-break-insert", + // QString("%1 --source \"%2\" --line %3") + // .arg(condition,filename) + // .arg(breakpoint->line)); + } } } @@ -1261,12 +1290,15 @@ void DebugReader::runNextCmd() } //clang compatibility - if (pCmd->command == "-break-insert" && mDebugger->forceUTF8()) { + if (mDebugger->forceUTF8()) { params = pCmd->params.toUtf8(); } if (pCmd->command == "-var-create") { //hack for variable creation,to easy remember var expression - params = " - @ "+params; + if (mDebugger->debuggerType()==DebuggerType::LLDB_MI) + params = " - * "+params; + else + params = " - @ "+params; } else if (pCmd->command == "-var-list-children") { //hack for list variable children,to easy remember var expression params = " --all-values \"" + params+'\"'; @@ -1565,8 +1597,9 @@ QByteArray DebugReader::removeToken(const QByteArray &line) void DebugReader::asyncUpdate() { QMutexLocker locker(&mCmdQueueMutex); - if (mCmdQueue.isEmpty()) + if (mCmdQueue.isEmpty()) { postCommand("-var-update"," --all-values *",DebugCommandSource::HeartBeat); + } mAsyncUpdated = false; } diff --git a/RedPandaIDE/debugger.h b/RedPandaIDE/debugger.h index 6463703d..8d591dca 100644 --- a/RedPandaIDE/debugger.h +++ b/RedPandaIDE/debugger.h @@ -39,6 +39,11 @@ enum class DebugCommandSource { Other }; +enum class DebuggerType { + GDB, + LLDB_MI +}; + struct DebugCommand{ QString command; QString params; @@ -342,6 +347,7 @@ public: void sendAllWatchVarsToDebugger(); PWatchVar findWatchVar(const QString& expression); PWatchVar watchVarAt(const QModelIndex& index); + void refreshVars(); // void notifyWatchVarUpdated(PWatchVar var); std::shared_ptr backtraceModel(); @@ -360,6 +366,9 @@ public: bool forceUTF8() const; void setForceUTF8(bool newForceUTF8); + DebuggerType debuggerType() const; + void setDebuggerType(DebuggerType newDebuggerType); + signals: void evalValueReady(const QString& s); void memoryExamineReady(const QStringList& s); @@ -402,6 +411,7 @@ private: DebugReader *mReader; DebugTarget *mTarget; bool mForceUTF8; + DebuggerType mDebuggerType; int mLeftPageIndexBackup; qint64 mLastLoadtime; qint64 mProjectLastLoadtime; diff --git a/RedPandaIDE/gdbmiresultparser.cpp b/RedPandaIDE/gdbmiresultparser.cpp index 925eb243..0bea0e6f 100644 --- a/RedPandaIDE/gdbmiresultparser.cpp +++ b/RedPandaIDE/gdbmiresultparser.cpp @@ -374,12 +374,22 @@ int GDBMIResultParser::ParseValue::hexValue(int defaultValue) const QString GDBMIResultParser::ParseValue::pathValue() const { //Q_ASSERT(mType == ParseValueType::Value); - return QFileInfo(QString::fromLocal8Bit(mValue)).absoluteFilePath(); + QByteArray value=mValue; +#ifdef Q_OS_WIN + if (value.startsWith("/") && !value.startsWith("//")) + value=value.mid(1); +#endif + return QFileInfo(QString::fromLocal8Bit(value)).absoluteFilePath(); } QString GDBMIResultParser::ParseValue::utf8PathValue() const { - return QFileInfo(QString::fromUtf8(mValue)).absoluteFilePath(); + QByteArray value=mValue; +#ifdef Q_OS_WIN + if (value.startsWith("/") && !value.startsWith("//")) + value=value.mid(1); +#endif + return QFileInfo(QString::fromUtf8(value)).absoluteFilePath(); } GDBMIResultParser::ParseValueType GDBMIResultParser::ParseValue::type() const diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index f13dad96..e1ce840c 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -1001,11 +1001,13 @@ void MainWindow::removeActiveBreakpoints() } } -void MainWindow::setActiveBreakpoint(QString FileName, int Line, bool setFocus) +void MainWindow::setActiveBreakpoint(QString fileName, int Line, bool setFocus) { removeActiveBreakpoints(); + if (!fileExists(fileName)) + return; // Then active the current line in the current file - Editor *e = openFile(FileName); + Editor *e = openFile(fileName); if (e!=nullptr) { e->setActiveBreakpointFocus(Line,setFocus); } diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index 4fd996a7..d2126573 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -2305,8 +2305,13 @@ void Settings::CompilerSet::setExecutables() if (mCompilerType == CompilerType::Clang) { mCCompiler = findProgramInBinDirs(CLANG_PROGRAM); mCppCompiler = findProgramInBinDirs(CLANG_CPP_PROGRAM); - mDebugger = findProgramInBinDirs(GDB_PROGRAM); - mDebugServer = findProgramInBinDirs(GDB_SERVER_PROGRAM); + mDebugger = findProgramInBinDirs(LLDB_MI_PROGRAM); + if (mDebugger.isEmpty()) { + mDebugger = findProgramInBinDirs(GDB_PROGRAM); + mDebugServer = findProgramInBinDirs(GDB_SERVER_PROGRAM); + } else { + mDebugServer = findProgramInBinDirs(LLDB_SERVER_PROGRAM); + } if (mCCompiler.isEmpty()) mCCompiler = findProgramInBinDirs(GCC_PROGRAM); if (mCppCompiler.isEmpty()) diff --git a/RedPandaIDE/systemconsts.h b/RedPandaIDE/systemconsts.h index aec8dc5d..a57059ac 100644 --- a/RedPandaIDE/systemconsts.h +++ b/RedPandaIDE/systemconsts.h @@ -36,6 +36,7 @@ #define CLANG_PROGRAM "clang.exe" #define CLANG_CPP_PROGRAM "clang++.exe" #define LLDB_MI_PROGRAM "lldb-mi.exe" +#define LLDB_SERVER_PROGRAM "lldb-server.exe" #elif defined(Q_OS_LINUX) #define CONSOLE_PAUSER "consolepauser" #define GCC_PROGRAM "gcc" @@ -52,6 +53,7 @@ #define CLANG_PROGRAM "clang" #define CLANG_CPP_PROGRAM "clang++" #define LLDB_MI_PROGRAM "lldb-mi" +#define LLDB_SERVER_PROGRAM "lldb-server" #elif defined(Q_OS_MACOS) #define GCC_PROGRAM "gcc" #define GPP_PROGRAM "g++" @@ -67,8 +69,9 @@ #define CLANG_PROGRAM "clang" #define CLANG_CPP_PROGRAM "clang++" #define LLDB_MI_PROGRAM "lldb-mi" +#define LLDB_SERVER_PROGRAM "lldb-server" #else -#error "Only support windows and linux now!" +#error "Only support windows, Linux and MacOS now!" #endif #define DEV_PROJECT_EXT "dev"