Conversation
WalkthroughReworked diagnostic logging: removed ModbusMaster signal-based logging, renamed logInfo → logDebug and switched to scoped/debug streams; removed ModbusPoll handlers for those signals; updated ScopeLogging signatures/formatting; reduced an initial startup log; bumped version to 4.2.1. Changes
Possibly related PRs
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/dialogs/diagnosticdialog.cpp (1)
202-215:⚠️ Potential issue | 🔴 CriticalBug: proxy model indices are used against the source model without mapping.
_pUi->listErroruses_pSeverityProxyFilteras its model, soselectedRows()returns proxy indices. Usingindex.row()directly with_pDiagnosticModel->toString(...)will copy the wrong rows whenever the filter hides any entries.🐛 Proposed fix: map proxy index to source index
foreach (QModelIndex index, indexlist) { - clipboardText.append(QString("%1\n").arg(_pDiagnosticModel->toString(index.row()))); + QModelIndex sourceIndex = _pSeverityProxyFilter->mapToSource(index); + clipboardText.append(QString("%1\n").arg(_pDiagnosticModel->toString(sourceIndex.row()))); }
🧹 Nitpick comments (2)
src/communication/modbusmaster.cpp (1)
240-248: Consider passingQStringby const reference.Both
logDebugandlogErrortakeQStringby value. Since they only read the string,const QString&avoids unnecessary copies.♻️ Suggested change
In the header (
modbusmaster.h):- void logDebug(QString msg); - void logError(QString msg); + void logDebug(const QString& msg); + void logError(const QString& msg);In the implementation:
-void ModbusMaster::logDebug(QString msg) +void ModbusMaster::logDebug(const QString& msg) { qCDebug(scopeCommConnection) << QString("[Conn %0] %1").arg(_connectionId + 1).arg(msg); } -void ModbusMaster::logError(QString msg) +void ModbusMaster::logError(const QString& msg) { qCWarning(scopeCommConnection) << QString("[Conn %0] %1").arg(_connectionId + 1).arg(msg); }src/util/scopelogging.cpp (1)
34-34: Commented-out code.This commented-out filter rule could be removed if it's no longer needed, or given a short comment explaining when it might be re-enabled.
56504a6 to
698bf3e
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/communication/modbusmaster.cpp (1)
224-232:⚠️ Potential issue | 🟠 MajorBug:
dStream << &listprints the pointer address, not the list contents.Line 229 passes the address of
listtoQDebug, which prints a hexadecimal pointer value instead of the list elements. This is inconsistent with line 219 wheremapis passed by value and prints the map contents. QDebug has an overload forconst QList<T>&that prints contents, but the pointer overload prints only the address.🐛 Proposed fix
- dStream << &list; + dStream << list;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/communication/modbusmaster.cpp` around lines 224 - 232, In ModbusMaster::dumpToString, replace the pointer being streamed (dStream << &list) with the actual QList to print its contents: change the QDebug call to stream `list` (i.e., dStream << list) so QDebug uses the QList overload and outputs elements; optionally consider accepting the parameter as const QList<ModbusDataUnit>& to avoid copying, but the immediate fix is to stop passing &list and pass list directly in the dStream << expression.
🧹 Nitpick comments (2)
src/util/scopelogging.cpp (1)
34-34: Commented-out code left behind.If this filter rule is no longer needed, consider removing it rather than leaving it commented out. If it's kept as a developer reference, a short explanatory comment would help.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/util/scopelogging.cpp` at line 34, Remove the leftover commented-out call to QLoggingCategory::setFilterRules("*=false\n") or add a concise explanatory comment if it must remain for developers; locate the occurrence of the commented line mentioning QLoggingCategory::setFilterRules in scopelogging.cpp and either delete that commented line or replace it with a short note explaining why the filter rule is kept commented (when/where to enable it) so the intent is clear.src/communication/modbusmaster.cpp (1)
58-58: String formatting overhead when debug logging is disabled.
dumpToString()and string concatenation at each call site are evaluated unconditionally, even when thescopeCommConnectiondebug category is disabled. On a hot polling path this is wasteful. Consider guarding with an early check:void ModbusMaster::logDebug(const QString& msg) { if (scopeCommConnection().isDebugEnabled()) qCDebug(scopeCommConnection) << QString("[Conn %0] %1").arg(_connectionId + 1).arg(msg); }However, note this only avoids the
qCDebugformatting — the caller-side string building (includingdumpToString) still runs. For a complete fix, callers would need to checkscopeCommConnection().isDebugEnabled()before constructing the message, or use a macro/lambda pattern.Also applies to: 119-119, 179-180, 236-236
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/communication/modbusmaster.cpp` at line 58, The debug message construction currently calls dumpToString() and concatenates strings unconditionally (e.g., in the register read log site that calls logDebug("Register list read: " + dumpToString(registerList))), causing unnecessary work when scopeCommConnection() debug is disabled; fix by guarding caller-side message construction with if (scopeCommConnection().isDebugEnabled()) before calling dumpToString() and logDebug(), or change usages to pass already-checked/lazy-evaluated messages into ModbusMaster::logDebug; locate references to dumpToString, the logDebug method, and call sites in ModbusMaster where messages are built (including the Register list read call and the other occurrences noted) and wrap those call sites with the debug-enabled check to avoid unneeded string formatting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@CHANGELOG.md`:
- Line 15: The changelog entry uses incorrect grammar ("less logs"); update the
sentence in CHANGELOG.md where the line reads "Rework diagnostic logging to
generate less logs when extensive logging is disabled" to use "fewer logs"
instead of "less logs" so it reads "Rework diagnostic logging to generate fewer
logs when extensive logging is disabled".
---
Outside diff comments:
In `@src/communication/modbusmaster.cpp`:
- Around line 224-232: In ModbusMaster::dumpToString, replace the pointer being
streamed (dStream << &list) with the actual QList to print its contents: change
the QDebug call to stream `list` (i.e., dStream << list) so QDebug uses the
QList overload and outputs elements; optionally consider accepting the parameter
as const QList<ModbusDataUnit>& to avoid copying, but the immediate fix is to
stop passing &list and pass list directly in the dStream << expression.
---
Nitpick comments:
In `@src/communication/modbusmaster.cpp`:
- Line 58: The debug message construction currently calls dumpToString() and
concatenates strings unconditionally (e.g., in the register read log site that
calls logDebug("Register list read: " + dumpToString(registerList))), causing
unnecessary work when scopeCommConnection() debug is disabled; fix by guarding
caller-side message construction with if
(scopeCommConnection().isDebugEnabled()) before calling dumpToString() and
logDebug(), or change usages to pass already-checked/lazy-evaluated messages
into ModbusMaster::logDebug; locate references to dumpToString, the logDebug
method, and call sites in ModbusMaster where messages are built (including the
Register list read call and the other occurrences noted) and wrap those call
sites with the debug-enabled check to avoid unneeded string formatting.
In `@src/util/scopelogging.cpp`:
- Line 34: Remove the leftover commented-out call to
QLoggingCategory::setFilterRules("*=false\n") or add a concise explanatory
comment if it must remain for developers; locate the occurrence of the commented
line mentioning QLoggingCategory::setFilterRules in scopelogging.cpp and either
delete that commented line or replace it with a short note explaining why the
filter rule is kept commented (when/where to enable it) so the intent is clear.
698bf3e to
58b932a
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/communication/modbusmaster.cpp`:
- Around line 182-183: The log call in handleTriggerNextRequest builds a QString
with invalid %0 placeholder so readItem.count() is never shown; change the
format to use valid %1 and %2 placeholders (e.g. "Start address (%1) and count
(%2)"), keep the arg(...) order as
arg(readItem.address().toString()).arg(readItem.count()), and wrap the
logDebug(...) invocation in an isDebugEnabled() check to avoid unneeded string
construction when debug logging is off; target the logDebug(...) call that
references readItem in handleTriggerNextRequest.
- Around line 247-254: The format strings in ModbusMaster logging use invalid
"%0" placeholders which prevents proper substitution; update the format
templates in ModbusMaster::logDebug and ModbusMaster::logError from "[Conn %0]
%1" to "[Conn %1] %2" and adjust the corresponding .arg() call order to
.arg(_connectionId + 1).arg(msg); also fix the similar string "Start address
(%0) and count (%1)" to "Start address (%1) and count (%2)"; review other
affected messages referenced in the comment (e.g., the "Modbus Exception: %0"
and "Request Failed: %0 (%1)" call sites) and replace %0/%1 with %1/%2 as needed
so all .arg() substitutions match valid %1..%99 placeholders.
src/communication/modbusmaster.cpp
Outdated
| logDebug("Partial list read: " + | ||
| QString("Start address (%0) and count (%1)").arg(readItem.address().toString()).arg(readItem.count())); |
There was a problem hiding this comment.
Same %0 bug at this call site — readItem.count() is silently dropped
QString("Start address (%0) and count (%1)")
.arg(readItem.address().toString()) // replaces %1 with address
.arg(readItem.count()) // %0 is invalid → count never appearsThe partial-read log message will show the address but never the count, and will contain a literal %0.
Additionally, unlike the comparable blocks at lines 58–61 and 239–242, this string is constructed unconditionally on every iteration of handleTriggerNextRequest. Wrapping it in isDebugEnabled() would keep the pattern consistent — although the individual arg() calls here are cheap.
🐛 Proposed fix
- logDebug("Partial list read: " +
- QString("Start address (%0) and count (%1)").arg(readItem.address().toString()).arg(readItem.count()));
+ if (scopeCommConnection().isDebugEnabled())
+ {
+ logDebug("Partial list read: " +
+ QString("Start address (%1) and count (%2)").arg(readItem.address().toString()).arg(readItem.count()));
+ }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/communication/modbusmaster.cpp` around lines 182 - 183, The log call in
handleTriggerNextRequest builds a QString with invalid %0 placeholder so
readItem.count() is never shown; change the format to use valid %1 and %2
placeholders (e.g. "Start address (%1) and count (%2)"), keep the arg(...) order
as arg(readItem.address().toString()).arg(readItem.count()), and wrap the
logDebug(...) invocation in an isDebugEnabled() check to avoid unneeded string
construction when debug logging is off; target the logDebug(...) call that
references readItem in handleTriggerNextRequest.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
tests/communication/tst_modbusdataunit.cpp (1)
68-73: LGTM — test correctly validates the fixed format string.As a nice-to-have, consider covering the other
ObjectTypevariants (e.g.COIL,HOLDING_REGISTER) to pin the full range ofModbusAddress::toString()output alongside the slave-id suffix:🧪 Optional: parametrised object-type coverage
void TestModbusDataUnit::toString() { ModbusDataUnit unit(123, ModbusAddress::ObjectType::INPUT_REGISTER, 42); QString expected = "input register, 123, slave id 42"; QCOMPARE(unit.toString(), expected); + + ModbusDataUnit unit2(1, ModbusAddress::ObjectType::COIL, 1); + QVERIFY(unit2.toString().endsWith(", slave id 1")); + + ModbusDataUnit unit3(40001, ModbusAddress::ObjectType::HOLDING_REGISTER, 255); + QVERIFY(unit3.toString().endsWith(", slave id 255")); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/communication/tst_modbusdataunit.cpp` around lines 68 - 73, Current test only asserts the INPUT_REGISTER output; extend TestModbusDataUnit::toString to cover all ModbusAddress::ObjectType variants by adding parametrised cases (or a small loop) that constructs ModbusDataUnit with each ObjectType (e.g., COIL, DISCRETE_INPUT, HOLDING_REGISTER, INPUT_REGISTER), builds the corresponding expected string using ModbusAddress::toString() semantic (e.g., "coil, <address>, slave id <id>" / "holding register, <address>, slave id <id>"), and QCOMPAREs unit.toString() against each expected value so the test pins full range of ModbusAddress::toString() outputs plus the slave-id suffix; reference TestModbusDataUnit::toString, ModbusDataUnit, and ModbusAddress::ObjectType when locating the code to modify.src/importexport/datafileexporter.cpp (1)
361-370: Correct%0-based →%1-based fix; consider hardening against%Nin substituted values.The 9-placeholder chained
.arg()approach is functionally correct for typical serial port names. However, with chained calls, if any earlier substituted value (e.g.portName()) happened to contain a%2–%9literal, subsequent.arg()calls would over-substitute it. Direct concatenation removes this ambiguity entirely:♻️ Optional: use string concatenation to avoid phantom substitution
- strSettings = QString("%1%2%3%4%5%6%7%8%9") - .arg(connData->portName()) - .arg(Util::separatorCharacter()) - .arg(connData->baudrate()) - .arg(Util::separatorCharacter()) - .arg(strParity) - .arg(Util::separatorCharacter()) - .arg(strDataBits) - .arg(Util::separatorCharacter()) - .arg(strStopBits); + const QChar sep = Util::separatorCharacter(); + strSettings = connData->portName() + + sep + QString::number(connData->baudrate()) + + sep + strParity + + sep + strDataBits + + sep + strStopBits;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/importexport/datafileexporter.cpp` around lines 361 - 370, Replace the chained nine-placeholder QString::arg() call that builds strSettings with direct concatenation of the individual components to avoid accidental "%N" substitution in values; specifically build strSettings from connData->portName(), Util::separatorCharacter(), connData->baudrate() (convert to QString if numeric), Util::separatorCharacter(), strParity, Util::separatorCharacter(), strDataBits, Util::separatorCharacter(), and strStopBits so no .arg() chaining is used and embedded percent sequences in portName() or other values cannot be re-interpreted.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/communication/modbusmaster.cpp`:
- Line 167: The log message passed to logError contains an accidental double
space in the QString literal used in the call logError(QString("Request Failed:
%1 (%2)").arg(errorString).arg(error)); — fix it by removing the extra space so
the literal becomes "Request Failed: %1 (%2)" (update the QString passed to
logError accordingly).
---
Duplicate comments:
In `@src/communication/modbusmaster.cpp`:
- Around line 182-183: The logDebug call that builds the "Partial list read"
string should be guarded by isDebugEnabled() to avoid unconditional string
construction; wrap the existing logDebug(...) that references
readItem.address().toString() and readItem.count() in an if (isDebugEnabled()) {
... } block (or equivalent check) to match the pattern used in the other debug
blocks and keep consistency with functions/methods using logDebug and
isDebugEnabled in ModbusMaster.
---
Nitpick comments:
In `@src/importexport/datafileexporter.cpp`:
- Around line 361-370: Replace the chained nine-placeholder QString::arg() call
that builds strSettings with direct concatenation of the individual components
to avoid accidental "%N" substitution in values; specifically build strSettings
from connData->portName(), Util::separatorCharacter(), connData->baudrate()
(convert to QString if numeric), Util::separatorCharacter(), strParity,
Util::separatorCharacter(), strDataBits, Util::separatorCharacter(), and
strStopBits so no .arg() chaining is used and embedded percent sequences in
portName() or other values cannot be re-interpreted.
In `@tests/communication/tst_modbusdataunit.cpp`:
- Around line 68-73: Current test only asserts the INPUT_REGISTER output; extend
TestModbusDataUnit::toString to cover all ModbusAddress::ObjectType variants by
adding parametrised cases (or a small loop) that constructs ModbusDataUnit with
each ObjectType (e.g., COIL, DISCRETE_INPUT, HOLDING_REGISTER, INPUT_REGISTER),
builds the corresponding expected string using ModbusAddress::toString()
semantic (e.g., "coil, <address>, slave id <id>" / "holding register, <address>,
slave id <id>"), and QCOMPAREs unit.toString() against each expected value so
the test pins full range of ModbusAddress::toString() outputs plus the slave-id
suffix; reference TestModbusDataUnit::toString, ModbusDataUnit, and
ModbusAddress::ObjectType when locating the code to modify.
| void ModbusMaster::handleRequestError(QString errorString, QModbusDevice::Error error) | ||
| { | ||
| logError(QString("Request Failed: %0 (%1)").arg(errorString).arg(error)); | ||
| logError(QString("Request Failed: %1 (%2)").arg(errorString).arg(error)); |
There was a problem hiding this comment.
Double space in log message string.
"Request Failed: %1 (%2)" contains two consecutive spaces before %1.
🔧 Proposed fix
- logError(QString("Request Failed: %1 (%2)").arg(errorString).arg(error));
+ logError(QString("Request Failed: %1 (%2)").arg(errorString).arg(error));📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| logError(QString("Request Failed: %1 (%2)").arg(errorString).arg(error)); | |
| logError(QString("Request Failed: %1 (%2)").arg(errorString).arg(error)); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/communication/modbusmaster.cpp` at line 167, The log message passed to
logError contains an accidental double space in the QString literal used in the
call logError(QString("Request Failed: %1 (%2)").arg(errorString).arg(error));
— fix it by removing the extra space so the literal becomes "Request Failed: %1
(%2)" (update the QString passed to logError accordingly).
|



Summary by CodeRabbit
Changes
Tests
Chores