From 742956d46cd610515eb96a771d8b94ba8528cf5e Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Sat, 17 Sep 2022 12:33:15 -0500 Subject: [PATCH 1/4] Working on finding a way to prevent bad_alloc crash, temp stuff in place like prealloc size, and frames list resize (prob need to keep list below size limit to prevent chaos...10M msgs or so mabe) --- canframemodel.cpp | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 735236b..4945679 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -49,7 +49,7 @@ CANFrameModel::CANFrameModel(QObject *parent) if (QSysInfo::WordSize > 32) { qDebug() << "64 bit OS detected. Requesting a large preallocation"; - preallocSize = 10000000; + preallocSize = 10000; //000; } else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down. { @@ -673,13 +673,39 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) if (!overwriteDups) { - frames.append(tempFrame); - if (filters[tempFrame.frameId()] && busFilters[tempFrame.bus]) + bool alloc_ok = true; + + for(int i=0; i<3; i++) { - if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count()); - tempFrame.frameCount = 1; - filteredFrames.append(tempFrame); - if (autoRefresh) endInsertRows(); + try + { + if(alloc_ok == false) + { + qDebug() << "Trying to remove " << (frames.length() >> 3) << " from frames. Try #" << i ; + frames.remove(0, frames.length() >> 3); + qDebug() << "frames length now: " << (frames.length()) << "trying to alloc again" ; + alloc_ok = true; + } + + frames.append(tempFrame); + break; + } + catch (const std::exception& ex) + { + alloc_ok = false; + qDebug() << "addFrame failed to append. frames.length(): " << frames.length() << " Exception: " << ex.what(); + } + } + + if(alloc_ok) + { + if (filters[tempFrame.frameId()] && busFilters[tempFrame.bus]) + { + if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count()); + tempFrame.frameCount = 1; + filteredFrames.append(tempFrame); + if (autoRefresh) endInsertRows(); + } } } else //yes, overwrite dups @@ -779,7 +805,7 @@ int CANFrameModel::sendBulkRefresh() if (lastUpdateNumFrames == 0 && !overwriteDups) return 0; if (filteredFrames.count() == 0) return 0; - qDebug() << "Bulk refresh of " << lastUpdateNumFrames; + //qDebug() << "Bulk refresh of " << lastUpdateNumFrames; beginResetModel(); endResetModel(); From 195c90c4154cd22ddb2e2b22489f14608e894f33 Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Sun, 18 Sep 2022 13:01:34 -0500 Subject: [PATCH 2/4] change the max amount of the reserved space for the frames and filteredFrames vectors to be 99% of the capacity instead of 95%. Reset initial capacity to be 10M frames for 64-bit machines now that testing is done. Want to make the capacity adjustable by user, too. --- canframemodel.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 4945679..616978b 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -49,7 +49,7 @@ CANFrameModel::CANFrameModel(QObject *parent) if (QSysInfo::WordSize > 32) { qDebug() << "64 bit OS detected. Requesting a large preallocation"; - preallocSize = 10000; //000; + preallocSize = 10000000; } else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down. { @@ -679,14 +679,6 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) { try { - if(alloc_ok == false) - { - qDebug() << "Trying to remove " << (frames.length() >> 3) << " from frames. Try #" << i ; - frames.remove(0, frames.length() >> 3); - qDebug() << "frames length now: " << (frames.length()) << "trying to alloc again" ; - alloc_ok = true; - } - frames.append(tempFrame); break; } @@ -754,6 +746,20 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false) void CANFrameModel::addFrames(const CANConnection*, const QVector& pFrames) { + if(frames.length() > frames.capacity() * 0.99) + { + qDebug() << "Frames count: " << frames.length() << " of " << frames.capacity() << " capacity, removing first " << frames.capacity() * 0.05 << " frames"; + frames.remove(0, frames.capacity() * 0.05); + qDebug() << "Frames removed, new count: " << frames.length(); + } + + if(filteredFrames.length() > filteredFrames.capacity() * 0.99) + { + qDebug() << "filteredFrames count: " << filteredFrames.length() << " of " << filteredFrames.capacity() << " capacity, removing first " << filteredFrames.capacity() * 0.05 << " frames"; + filteredFrames.remove(0, filteredFrames.capacity() * 0.05); + qDebug() << "filteredFrames removed, new count: " << filteredFrames.length(); + } + foreach(const CANFrame& frame, pFrames) { addFrame(frame); From d56b35ea91bf40be0af57cd6185917d3d1588b95 Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Mon, 19 Sep 2022 13:10:33 -0500 Subject: [PATCH 3/4] Made max # of frames an option in preferences, restart to take effect --- canframemodel.cpp | 10 +++++++--- mainsettingsdialog.cpp | 16 ++++++++++++++++ ui/mainsettingsdialog.ui | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index 616978b..c4a8309 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "utility.h" CANFrameModel::~CANFrameModel() @@ -45,18 +46,21 @@ int CANFrameModel::columnCount(const QModelIndex &index) const CANFrameModel::CANFrameModel(QObject *parent) : QAbstractTableModel(parent) { - + int maxFramesDefault; if (QSysInfo::WordSize > 32) { qDebug() << "64 bit OS detected. Requesting a large preallocation"; - preallocSize = 10000000; + maxFramesDefault = 10000000; } else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down. { qDebug() << "32 bit OS detected. Requesting a much restricted prealloc"; - preallocSize = 2000000; + maxFramesDefault = 2000000; } + QSettings settings; + int preallocSize = settings.value("Main/MaximumFrames", maxFramesDefault).toInt(); + frames.reserve(preallocSize); filteredFrames.reserve(preallocSize); //the goal is to prevent a reallocation from ever happening diff --git a/mainsettingsdialog.cpp b/mainsettingsdialog.cpp index 77bf257..2da44ed 100644 --- a/mainsettingsdialog.cpp +++ b/mainsettingsdialog.cpp @@ -90,6 +90,20 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) : ui->cbFilterLabeling->setChecked(settings.value("Main/FilterLabeling", true).toBool()); ui->cbIgnoreDBCColors->setChecked(settings.value("Main/IgnoreDBCColors", false).toBool()); + int maxFramesDefault; + if (QSysInfo::WordSize > 32) + { + qDebug() << "64 bit OS detected. Requesting a large preallocation"; + maxFramesDefault = 10000000; + } + else //if compiling for 32 bit you can't ask for gigabytes of preallocation so tone it down. + { + qDebug() << "32 bit OS detected. Requesting a much restricted prealloc"; + maxFramesDefault = 2000000; + } + + ui->spinMaximumFrames->setValue(settings.value("Main/MaximumFrames", maxFramesDefault).toInt()); + //just for simplicity they all call the same function and that function updates all settings at once connect(ui->cbDisplayHex, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); connect(ui->cbFlowAutoRef, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); @@ -117,6 +131,7 @@ MainSettingsDialog::MainSettingsDialog(QWidget *parent) : connect(ui->cbHexGraphFlow, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); connect(ui->cbHexGraphInfo, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); connect(ui->cbIgnoreDBCColors, SIGNAL(toggled(bool)), this, SLOT(updateSettings())); + connect(ui->spinMaximumFrames, SIGNAL(valueChanged(int)), this, SLOT(updateSettings())); installEventFilter(this); } @@ -183,6 +198,7 @@ void MainSettingsDialog::updateSettings() settings.setValue("Remote/Pass", encPass); settings.setValue("Main/FilterLabeling", ui->cbFilterLabeling->isChecked()); settings.setValue("Main/IgnoreDBCColors", ui->cbIgnoreDBCColors->isChecked()); + settings.setValue("Main/MaximumFrames", ui->spinMaximumFrames->value()); settings.sync(); emit updatedSettings(); diff --git a/ui/mainsettingsdialog.ui b/ui/mainsettingsdialog.ui index 586e4e0..d119b08 100644 --- a/ui/mainsettingsdialog.ui +++ b/ui/mainsettingsdialog.ui @@ -80,6 +80,39 @@ + + + + 0 + + + 0 + + + + + Maximum Frames to Capture + + + + + + + 100000 + + + 1000000000 + + + 100000 + + + 10000000 + + + + + From cb94cac2057cab2121bccfce0f4255e100e017bb Mon Sep 17 00:00:00 2001 From: Andy Huska Date: Mon, 19 Sep 2022 13:47:57 -0500 Subject: [PATCH 4/4] Fixed issue where filteredFrames was having its capacity changed when adjusting filters due to appending a QVector of frames which appears to change the capacity to the number of items appended. Also fixed bug where preallocsize was being locally defined and therefore the global version wasn't being updated with unknown effets. --- canframemodel.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/canframemodel.cpp b/canframemodel.cpp index c4a8309..cdcaa19 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -59,7 +59,7 @@ CANFrameModel::CANFrameModel(QObject *parent) } QSettings settings; - int preallocSize = settings.value("Main/MaximumFrames", maxFramesDefault).toInt(); + preallocSize = settings.value("Main/MaximumFrames", maxFramesDefault).toInt(); frames.reserve(preallocSize); filteredFrames.reserve(preallocSize); //the goal is to prevent a reallocation from ever happening @@ -752,15 +752,15 @@ void CANFrameModel::addFrames(const CANConnection*, const QVector& pFr { if(frames.length() > frames.capacity() * 0.99) { - qDebug() << "Frames count: " << frames.length() << " of " << frames.capacity() << " capacity, removing first " << frames.capacity() * 0.05 << " frames"; - frames.remove(0, frames.capacity() * 0.05); + qDebug() << "Frames count: " << frames.length() << " of " << frames.capacity() << " capacity, removing first " << (int)(frames.capacity() * 0.05) << " frames"; + frames.remove(0, (int)(frames.capacity() * 0.05)); qDebug() << "Frames removed, new count: " << frames.length(); } if(filteredFrames.length() > filteredFrames.capacity() * 0.99) { - qDebug() << "filteredFrames count: " << filteredFrames.length() << " of " << filteredFrames.capacity() << " capacity, removing first " << filteredFrames.capacity() * 0.05 << " frames"; - filteredFrames.remove(0, filteredFrames.capacity() * 0.05); + qDebug() << "filteredFrames count: " << filteredFrames.length() << " of " << filteredFrames.capacity() << " capacity, removing first " << (int)(filteredFrames.capacity() * 0.05) << " frames"; + filteredFrames.remove(0, (int)(filteredFrames.capacity() * 0.05)); qDebug() << "filteredFrames removed, new count: " << filteredFrames.length(); } @@ -790,8 +790,8 @@ void CANFrameModel::sendRefresh() mutex.lock(); beginResetModel(); filteredFrames.clear(); - filteredFrames.reserve(preallocSize); filteredFrames.append(tempContainer); + filteredFrames.reserve(preallocSize); lastUpdateNumFrames = 0; endResetModel();