Skip to content

Fix rolegroupmodel memoryleak#1562

Open
heysion wants to merge 11 commits intolinuxdeepin:masterfrom
heysion:fix-rolegroupmodel-memoryleak
Open

Fix rolegroupmodel memoryleak#1562
heysion wants to merge 11 commits intolinuxdeepin:masterfrom
heysion:fix-rolegroupmodel-memoryleak

Conversation

@heysion
Copy link
Copy Markdown
Member

@heysion heysion commented Apr 16, 2026

use ASan detected memory leak

Test project /home/test/dde-env/src/dde-shell/build
      Start 11: RoleGroupModel.RowCountTest
 1/11 Test #11: RoleGroupModel.RowCountTest .....................***Failed    0.05 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.RowCountTest
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.RowCountTest
[       OK ] RoleGroupModel.RowCountTest (1 ms)
[----------] 1 test from RoleGroupModel (1 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (1 ms total)
[  PASSED  ] 1 test.

=================================================================
==269701==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 48 byte(s) in 2 object(s) allocated from:
    #0 0x7fc7a945ccd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x557889b19c53 in RoleGroupModel::rebuildTreeSource() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:320
    #2 0x557889b10da6 in operator() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:94
    #3 0x557889b1d468 in operator() /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:141
    #4 0x557889b1d991 in call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1, 2>, QtPrivate::List<const QModelIndex&, const QModelIndex&, const QList<int>&>, void, RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, const QModelIndex&, const QList<int>&)> >::call(RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, const QModelIndex&, const QList<int>&)>&, void**)::<lambda()> > /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:65
    #5 0x557889b1d5ad in call /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:140
    #6 0x557889b1c2d3 in call<QtPrivate::List<const QModelIndex&, const QModelIndex&, const QList<int>&>, void> /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:362
    #7 0x557889b1bf0b in impl /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:572
    #8 0x7fc7a875446b  (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x1a646b)
    #9 0x7fc7a88bccaf in QAbstractItemModel::dataChanged(QModelIndex const&, QModelIndex const&, QList<int> const&) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x30ecaf)
    #10 0x5120000016bf  (<unknown module>)

Indirect leak of 64 byte(s) in 2 object(s) allocated from:
    #0 0x7fc7a945c1cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7fc7a87e16d7 in QArrayData::allocate(QArrayData**, long long, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2336d7)

SUMMARY: AddressSanitizer: 112 byte(s) leaked in 4 allocation(s).

      Start 12: RoleGroupModel.IndexMethodDeepTest
 2/11 Test #12: RoleGroupModel.IndexMethodDeepTest ..............***Failed    0.05 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.IndexMethodDeepTest
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.IndexMethodDeepTest
[       OK ] RoleGroupModel.IndexMethodDeepTest (0 ms)
[----------] 1 test from RoleGroupModel (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 1 test.

=================================================================
==269703==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7fbe53b98cd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x55dfa4d43290 in operator() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:55
    #2 0x55dfa4d51826 in operator() /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:141
    #3 0x55dfa4d52899 in call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1, 2>, QtPrivate::List<const QModelIndex&, int, int>, void, RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, int, int)> >::call(RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, int, int)>&, void**)::<lambda()> > /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:65
    #4 0x55dfa4d5196b in call /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:140
    #5 0x55dfa4d511af in call<QtPrivate::List<const QModelIndex&, int, int>, void> /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:362
    #6 0x55dfa4d50b67 in impl /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:572
    #7 0x7fbe52e9046b  (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x1a646b)
    #8 0x7fbe52ff8f21 in QAbstractItemModel::rowsInserted(QModelIndex const&, int, int, QAbstractItemModel::QPrivateSignal) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x30ef21)
    #9 0x5120000016bf  (<unknown module>)

Indirect leak of 32 byte(s) in 1 object(s) allocated from:
    #0 0x7fbe53b981cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7fbe52f1d6d7 in QArrayData::allocate(QArrayData**, long long, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2336d7)

SUMMARY: AddressSanitizer: 56 byte(s) leaked in 2 allocation(s).

      Start 13: RoleGroupModel.ModelTesterValidation
 3/11 Test #13: RoleGroupModel.ModelTesterValidation ............***Failed    0.05 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.ModelTesterValidation
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.ModelTesterValidation
[       OK ] RoleGroupModel.ModelTesterValidation (2 ms)
[----------] 1 test from RoleGroupModel (2 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (2 ms total)
[  PASSED  ] 1 test.

=================================================================
==269705==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 96 byte(s) in 4 object(s) allocated from:
    #0 0x7fd723ec8cd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x559b7e745c53 in RoleGroupModel::rebuildTreeSource() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:320
    #2 0x559b7e73cda6 in operator() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:94
    #3 0x559b7e749468 in operator() /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:141
    #4 0x559b7e749991 in call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1, 2>, QtPrivate::List<const QModelIndex&, const QModelIndex&, const QList<int>&>, void, RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, const QModelIndex&, const QList<int>&)> >::call(RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, const QModelIndex&, const QList<int>&)>&, void**)::<lambda()> > /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:65
    #5 0x559b7e7495ad in call /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:140
    #6 0x559b7e7482d3 in call<QtPrivate::List<const QModelIndex&, const QModelIndex&, const QList<int>&>, void> /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:362
    #7 0x559b7e747f0b in impl /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:572
    #8 0x7fd7231c046b  (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x1a646b)
    #9 0x7fd723328caf in QAbstractItemModel::dataChanged(QModelIndex const&, QModelIndex const&, QList<int> const&) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x30ecaf)
    #10 0x5120000016bf  (<unknown module>)

Indirect leak of 128 byte(s) in 4 object(s) allocated from:
    #0 0x7fd723ec81cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7fd72324d6d7 in QArrayData::allocate(QArrayData**, long long, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2336d7)

SUMMARY: AddressSanitizer: 224 byte(s) leaked in 8 allocation(s).

      Start 15: RoleGroupModel.DestructorMemoryLeakTest
 4/11 Test #15: RoleGroupModel.DestructorMemoryLeakTest .........***Failed    0.05 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.DestructorMemoryLeakTest
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.DestructorMemoryLeakTest
[       OK ] RoleGroupModel.DestructorMemoryLeakTest (0 ms)
[----------] 1 test from RoleGroupModel (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 1 test.

=================================================================
==269707==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 48 byte(s) in 2 object(s) allocated from:
    #0 0x7f12e03c9cd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x5654011b9c53 in RoleGroupModel::rebuildTreeSource() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:320
    #2 0x5654011b26ad in RoleGroupModel::setSourceModel(QAbstractItemModel*) /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:37
    #3 0x5654011acb18 in RoleGroupModel::RoleGroupModel(QAbstractItemModel*, int, QObject*) /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:13
    #4 0x56540120a93f in RoleGroupModel_DestructorMemoryLeakTest_Test::TestBody() /home/test/dde-env/src/dde-shell/tests/panels/dock/taskmanager/rolegroupmodeltests.cpp:306
    #5 0x56540127ba4e in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (/home/test/dde-env/src/dde-shell/build/tests/panels/dock/taskmanager/rolegroupmodel_tests+0x1b6a4e)

Indirect leak of 64 byte(s) in 2 object(s) allocated from:
    #0 0x7f12e03c91cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7f12df74e6d7 in QArrayData::allocate(QArrayData**, long long, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2336d7)

SUMMARY: AddressSanitizer: 112 byte(s) leaked in 4 allocation(s).

      Start 16: RoleGroupModel.RebuildTreeSourceMemoryTest
 5/11 Test #16: RoleGroupModel.RebuildTreeSourceMemoryTest ......***Failed    0.05 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.RebuildTreeSourceMemoryTest
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.RebuildTreeSourceMemoryTest
[       OK ] RoleGroupModel.RebuildTreeSourceMemoryTest (0 ms)
[----------] 1 test from RoleGroupModel (1 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (1 ms total)
[  PASSED  ] 1 test.

=================================================================
==269709==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7fec9f0c0cd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x55bdb5303c53 in RoleGroupModel::rebuildTreeSource() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:320
    #2 0x55bdb52fada6 in operator() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:94
    #3 0x55bdb5307468 in operator() /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:141
    #4 0x55bdb5307991 in call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1, 2>, QtPrivate::List<const QModelIndex&, const QModelIndex&, const QList<int>&>, void, RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, const QModelIndex&, const QList<int>&)> >::call(RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, const QModelIndex&, const QList<int>&)>&, void**)::<lambda()> > /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:65
    #5 0x55bdb53075ad in call /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:140
    #6 0x55bdb53062d3 in call<QtPrivate::List<const QModelIndex&, const QModelIndex&, const QList<int>&>, void> /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:362
    #7 0x55bdb5305f0b in impl /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:572
    #8 0x7fec9e3b846b  (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x1a646b)
    #9 0x7fec9e520caf in QAbstractItemModel::dataChanged(QModelIndex const&, QModelIndex const&, QList<int> const&) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x30ecaf)
    #10 0x5120000016bf  (<unknown module>)

Indirect leak of 32 byte(s) in 1 object(s) allocated from:
    #0 0x7fec9f0c01cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7fec9e4456d7 in QArrayData::allocate(QArrayData**, long long, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2336d7)

SUMMARY: AddressSanitizer: 56 byte(s) leaked in 2 allocation(s).

      Start 17: RoleGroupModel.SetSourceModelMemoryTest
 6/11 Test #17: RoleGroupModel.SetSourceModelMemoryTest .........***Failed    0.05 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.SetSourceModelMemoryTest
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.SetSourceModelMemoryTest
[       OK ] RoleGroupModel.SetSourceModelMemoryTest (1 ms)
[----------] 1 test from RoleGroupModel (1 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (1 ms total)
[  PASSED  ] 1 test.

=================================================================
==269711==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7f51a4fa0cd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x5622a5b04c53 in RoleGroupModel::rebuildTreeSource() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:320
    #2 0x5622a5afd6ad in RoleGroupModel::setSourceModel(QAbstractItemModel*) /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:37
    #3 0x5622a5b5b197 in RoleGroupModel_SetSourceModelMemoryTest_Test::TestBody() /home/test/dde-env/src/dde-shell/tests/panels/dock/taskmanager/rolegroupmodeltests.cpp:390
    #4 0x5622a5bc6a4e in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (/home/test/dde-env/src/dde-shell/build/tests/panels/dock/taskmanager/rolegroupmodel_tests+0x1b6a4e)

Indirect leak of 32 byte(s) in 1 object(s) allocated from:
    #0 0x7f51a4fa01cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7f51a43256d7 in QArrayData::allocate(QArrayData**, long long, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2336d7)

SUMMARY: AddressSanitizer: 56 byte(s) leaked in 2 allocation(s).

      Start 19: RoleGroupModel.LargeDataMemoryStabilityTest
 7/11 Test #19: RoleGroupModel.LargeDataMemoryStabilityTest .....***Failed    0.05 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.LargeDataMemoryStabilityTest
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.LargeDataMemoryStabilityTest
[       OK ] RoleGroupModel.LargeDataMemoryStabilityTest (2 ms)
[----------] 1 test from RoleGroupModel (2 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (2 ms total)
[  PASSED  ] 1 test.

=================================================================
==269713==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 360 byte(s) in 15 object(s) allocated from:
    #0 0x7f05e1fdacd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x55810281d290 in operator() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:55
    #2 0x55810282b826 in operator() /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:141
    #3 0x55810282c899 in call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1, 2>, QtPrivate::List<const QModelIndex&, int, int>, void, RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, int, int)> >::call(RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, int, int)>&, void**)::<lambda()> > /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:65
    #4 0x55810282b96b in call /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:140
    #5 0x55810282b1af in call<QtPrivate::List<const QModelIndex&, int, int>, void> /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:362
    #6 0x55810282ab67 in impl /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:572
    #7 0x7f05e12d246b  (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x1a646b)
    #8 0x7f05e143af21 in QAbstractItemModel::rowsInserted(QModelIndex const&, int, int, QAbstractItemModel::QPrivateSignal) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x30ef21)
    #9 0x5120000016bf  (<unknown module>)

Indirect leak of 960 byte(s) in 15 object(s) allocated from:
    #0 0x7f05e1fd90d5 in __interceptor_realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:85
    #1 0x7f05e135f9c7 in QArrayData::reallocateUnaligned(QArrayData*, void*, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2339c7)

SUMMARY: AddressSanitizer: 1320 byte(s) leaked in 30 allocation(s).

      Start 20: RoleGroupModel.SetDeduplicationRoleMemoryTest
 8/11 Test #20: RoleGroupModel.SetDeduplicationRoleMemoryTest ...***Failed    0.05 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.SetDeduplicationRoleMemoryTest
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.SetDeduplicationRoleMemoryTest
[       OK ] RoleGroupModel.SetDeduplicationRoleMemoryTest (0 ms)
[----------] 1 test from RoleGroupModel (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 1 test.

=================================================================
==269715==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7ff0ec992cd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x55e6edbb3c53 in RoleGroupModel::rebuildTreeSource() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:320
    #2 0x55e6edba7158 in RoleGroupModel::setDeduplicationRole(int const&) /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:20
    #3 0x55e6edc10af4 in RoleGroupModel_SetDeduplicationRoleMemoryTest_Test::TestBody() /home/test/dde-env/src/dde-shell/tests/panels/dock/taskmanager/rolegroupmodeltests.cpp:483
    #4 0x55e6edc75a4e in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (/home/test/dde-env/src/dde-shell/build/tests/panels/dock/taskmanager/rolegroupmodel_tests+0x1b6a4e)

Indirect leak of 64 byte(s) in 1 object(s) allocated from:
    #0 0x7ff0ec9910d5 in __interceptor_realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:85
    #1 0x7ff0ebd179c7 in QArrayData::reallocateUnaligned(QArrayData*, void*, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2339c7)

SUMMARY: AddressSanitizer: 88 byte(s) leaked in 2 allocation(s).

      Start 21: RoleGroupModel.RowsInsertedMemoryTest
 9/11 Test #21: RoleGroupModel.RowsInsertedMemoryTest ...........***Failed    0.04 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.RowsInsertedMemoryTest
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.RowsInsertedMemoryTest
[       OK ] RoleGroupModel.RowsInsertedMemoryTest (0 ms)
[----------] 1 test from RoleGroupModel (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 1 test.

=================================================================
==269717==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 48 byte(s) in 2 object(s) allocated from:
    #0 0x7f334946acd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x55de6c09e290 in operator() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:55
    #2 0x55de6c0ac826 in operator() /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:141
    #3 0x55de6c0ad899 in call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1, 2>, QtPrivate::List<const QModelIndex&, int, int>, void, RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, int, int)> >::call(RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, int, int)>&, void**)::<lambda()> > /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:65
    #4 0x55de6c0ac96b in call /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:140
    #5 0x55de6c0ac1af in call<QtPrivate::List<const QModelIndex&, int, int>, void> /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:362
    #6 0x55de6c0abb67 in impl /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:572
    #7 0x7f334876246b  (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x1a646b)
    #8 0x7f33488caf21 in QAbstractItemModel::rowsInserted(QModelIndex const&, int, int, QAbstractItemModel::QPrivateSignal) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x30ef21)
    #9 0x5120000016bf  (<unknown module>)

Indirect leak of 64 byte(s) in 2 object(s) allocated from:
    #0 0x7f334946a1cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7f33487ef6d7 in QArrayData::allocate(QArrayData**, long long, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2336d7)

SUMMARY: AddressSanitizer: 112 byte(s) leaked in 4 allocation(s).

      Start 23: RoleGroupModel.ModelResetMemoryTest
10/11 Test #23: RoleGroupModel.ModelResetMemoryTest .............***Failed    0.05 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.ModelResetMemoryTest
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.ModelResetMemoryTest
[       OK ] RoleGroupModel.ModelResetMemoryTest (0 ms)
[----------] 1 test from RoleGroupModel (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (1 ms total)
[  PASSED  ] 1 test.

=================================================================
==269719==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x7fa3faaeecd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x55b2740ea290 in operator() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:55
    #2 0x55b2740f8826 in operator() /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:141
    #3 0x55b2740f9899 in call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1, 2>, QtPrivate::List<const QModelIndex&, int, int>, void, RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, int, int)> >::call(RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, int, int)>&, void**)::<lambda()> > /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:65
    #4 0x55b2740f896b in call /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:140
    #5 0x55b2740f81af in call<QtPrivate::List<const QModelIndex&, int, int>, void> /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:362
    #6 0x55b2740f7b67 in impl /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:572
    #7 0x7fa3f9de646b  (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x1a646b)
    #8 0x7fa3f9f4ef21 in QAbstractItemModel::rowsInserted(QModelIndex const&, int, int, QAbstractItemModel::QPrivateSignal) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x30ef21)
    #9 0x5120000016bf  (<unknown module>)

Indirect leak of 32 byte(s) in 1 object(s) allocated from:
    #0 0x7fa3faaee1cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7fa3f9e736d7 in QArrayData::allocate(QArrayData**, long long, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2336d7)

SUMMARY: AddressSanitizer: 56 byte(s) leaked in 2 allocation(s).

      Start 24: RoleGroupModel.ScrollingBoundaryTest
11/11 Test #24: RoleGroupModel.ScrollingBoundaryTest ............***Failed    0.05 sec
Running main() from ./googletest/src/gtest_main.cc
Note: Google Test filter = RoleGroupModel.ScrollingBoundaryTest
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from RoleGroupModel
[ RUN      ] RoleGroupModel.ScrollingBoundaryTest
[       OK ] RoleGroupModel.ScrollingBoundaryTest (0 ms)
[----------] 1 test from RoleGroupModel (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (1 ms total)
[  PASSED  ] 1 test.

=================================================================
==269721==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 72 byte(s) in 3 object(s) allocated from:
    #0 0x7f5f104c2cd8 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x55c639508290 in operator() /home/test/dde-env/src/dde-shell/panels/dock/taskmanager/rolegroupmodel.cpp:55
    #2 0x55c639516826 in operator() /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:141
    #3 0x55c639517899 in call_internal<void, QtPrivate::FunctorCall<QtPrivate::IndexesList<0, 1, 2>, QtPrivate::List<const QModelIndex&, int, int>, void, RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, int, int)> >::call(RoleGroupModel::setSourceModel(QAbstractItemModel*)::<lambda(const QModelIndex&, int, int)>&, void**)::<lambda()> > /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:65
    #4 0x55c63951696b in call /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:140
    #5 0x55c6395161af in call<QtPrivate::List<const QModelIndex&, int, int>, void> /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:362
    #6 0x55c639515b67 in impl /usr/include/x86_64-linux-gnu/qt6/QtCore/qobjectdefs_impl.h:572
    #7 0x7f5f0f7ba46b  (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x1a646b)
    #8 0x7f5f0f922f21 in QAbstractItemModel::rowsInserted(QModelIndex const&, int, int, QAbstractItemModel::QPrivateSignal) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x30ef21)
    #9 0x5120000016bf  (<unknown module>)

Indirect leak of 96 byte(s) in 3 object(s) allocated from:
    #0 0x7f5f104c21cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x7f5f0f8476d7 in QArrayData::allocate(QArrayData**, long long, long long, long long, QArrayData::AllocationOption) (/lib/x86_64-linux-gnu/libQt6Core.so.6+0x2336d7)

SUMMARY: AddressSanitizer: 168 byte(s) leaked in 6 allocation(s).


0% tests passed, 11 tests failed out of 11

Total Test time (real) =   0.51 sec

The following tests FAILED:
	11 - RoleGroupModel.RowCountTest (Failed)
	12 - RoleGroupModel.IndexMethodDeepTest (Failed)
	13 - RoleGroupModel.ModelTesterValidation (Failed)
	15 - RoleGroupModel.DestructorMemoryLeakTest (Failed)
	16 - RoleGroupModel.RebuildTreeSourceMemoryTest (Failed)
	17 - RoleGroupModel.SetSourceModelMemoryTest (Failed)
	19 - RoleGroupModel.LargeDataMemoryStabilityTest (Failed)
	20 - RoleGroupModel.SetDeduplicationRoleMemoryTest (Failed)
	21 - RoleGroupModel.RowsInsertedMemoryTest (Failed)
	23 - RoleGroupModel.ModelResetMemoryTest (Failed)
	24 - RoleGroupModel.ScrollingBoundaryTest (Failed)
Errors while running CTest
ndk@sysnpc:/tmp/output-abc$ ssh sh-v25-vm "cd /home/test/dde-env/src/dde-shell/build && ctest --rerun-failed --output-on-failure"
Test project /home/test/dde-env/src/dde-shell/build
    Start 15: RoleGroupModel.DestructorMemoryLeakTest
1/1 Test #15: RoleGroupModel.DestructorMemoryLeakTest ...   Passed    0.02 sec

Summary by Sourcery

Fix memory leaks in task manager role grouping and extend test coverage for both dock task manager and notification server components.

Bug Fixes:

  • Ensure RoleGroupModel cleans up its internal mapping on destruction to prevent leaked group data.
  • Add proper destruction of test list model items and model tester instances used in task-related tests to avoid test-induced leaks.

Build:

  • Wire up new notification server tests under the panels tests hierarchy, creating the notifyserverapplet_tests target with required Qt, GTest, and project library dependencies.

Tests:

  • Add a suite of RoleGroupModel memory-management tests covering destruction, source model changes, model resets, row insert/remove paths, large data scenarios, and deduplication role changes.
  • Introduce comprehensive NotifyServerApplet tests, including constructor/destructor behavior, init and worker-thread setup, D-Bus-related API calls, and edge-case handling for notification operations and signals.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 16, 2026

Reviewer's Guide

Adds proper destruction and memory-management tests for RoleGroupModel and NotifyServerApplet, implements destructors/cleanup in RoleGroupModel, TestModelA/B, and introduces a new notification server test target, addressing ASan-reported leaks in taskmanager and notification components.

Class diagram for updated RoleGroupModel memory management

classDiagram
    class QAbstractProxyModel

    class RoleGroupModel {
        +RoleGroupModel(QAbstractItemModel* sourceModel, int role, QObject* parent)
        +~RoleGroupModel()
        +void setSourceModel(QAbstractItemModel* sourceModel)
        +void setDeduplicationRole(const int& role)
        -QHash<int, QObject*> m_map
        -void rebuildTreeSource()
    }

    RoleGroupModel --|> QAbstractProxyModel
Loading

File-Level Changes

Change Details Files
Ensure RoleGroupModel and related test models free internal containers to avoid ASan-detected leaks.
  • Add virtual destructor override to RoleGroupModel that deletes items stored in its internal map container using qDeleteAll
  • Declare and define destructors for TestModelA/TestModelB that delete and clear their internal item lists
  • Extend RoleGroupModel unit tests with several memory-focused scenarios around destruction, rebuilding, model switching, rows inserted/removed, model reset, and large data
panels/dock/taskmanager/rolegroupmodel.h
panels/dock/taskmanager/rolegroupmodel.cpp
tests/panels/dock/taskmanager/combinemodela.h
tests/panels/dock/taskmanager/combinemodela.cpp
tests/panels/dock/taskmanager/combinemodelb.h
tests/panels/dock/taskmanager/combinemodelb.cpp
tests/panels/dock/taskmanager/rolegroupmodeltests.cpp
Tighten lifetime management in existing tests by avoiding orphaned QAbstractItemModelTester instances.
  • Change RoleGroupModel model tester test to store QAbstractItemModelTester in a local pointer and delete it explicitly
tests/panels/dock/taskmanager/rolecombinemodeltests.cpp
Introduce a new GTest-based notification server test executable that exercises NotifyServerApplet initialization, teardown, and NotificationManager interactions for leak detection.
  • Create notification panel test CMakeLists to build a notifyserverapplet_tests binary and link against notification server/common sources and Qt/GTest
  • Implement a comprehensive notifyserverapplet_test.cpp with a MockNotificationManager and many behavioral and memory-leak oriented tests for NotifyServerApplet, including destructor, multiple init, action/close/remove paths, and signal wiring
  • Wire the notification test subtree into the main tests/panels CMake so it is built with the rest of the panel tests
tests/panels/CMakeLists.txt
tests/panels/notification/CMakeLists.txt
tests/panels/notification/server/CMakeLists.txt
tests/panels/notification/server/notifyserverapplet_test.cpp
Update SPDX copyright headers to reflect extended years.
  • Adjust panels and test CMakeLists SPDX-FileCopyrightText ranges to include 2026
tests/panels/dock/taskmanager/rolegroupmodeltests.cpp
tests/panels/CMakeLists.txt
tests/panels/notification/CMakeLists.txt

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In notifyserverapplet_test.cpp you both define a custom main() that creates a QCoreApplication and also create a QCoreApplication in the fixture SetUp; this will result in two application instances for the same test binary and should be simplified to a single creation point (or rely on gtest_main and remove the custom main).
  • The MockNotificationManager in notifyserverapplet_test.cpp is currently unused; either wire it into the tests (e.g., by injecting it into NotifyServerApplet) or remove it to avoid dead code and maintenance overhead.
  • In rolecombinemodeltests.cpp, instead of allocating QAbstractItemModelTester with new and deleting it manually, consider constructing it as an automatic (stack) variable so its lifetime is more obvious and exception-safe.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In notifyserverapplet_test.cpp you both define a custom main() that creates a QCoreApplication and also create a QCoreApplication in the fixture SetUp; this will result in two application instances for the same test binary and should be simplified to a single creation point (or rely on gtest_main and remove the custom main).
- The MockNotificationManager in notifyserverapplet_test.cpp is currently unused; either wire it into the tests (e.g., by injecting it into NotifyServerApplet) or remove it to avoid dead code and maintenance overhead.
- In rolecombinemodeltests.cpp, instead of allocating QAbstractItemModelTester with new and deleting it manually, consider constructing it as an automatic (stack) variable so its lifetime is more obvious and exception-safe.

## Individual Comments

### Comment 1
<location path="tests/panels/notification/server/notifyserverapplet_test.cpp" line_range="21-30" />
<code_context>
+using ::testing::Return;
+using ::testing::Invoke;
+
+// Mock class for NotificationManager
+class MockNotificationManager : public NotificationManager {
+    Q_OBJECT
+public:
+    explicit MockNotificationManager(QObject *parent = nullptr)
+        : NotificationManager(parent) {}
+
+    MOCK_METHOD(bool, registerDbusService, (), ());
+    MOCK_METHOD(void, actionInvoked, (qint64 id, uint bubbleId, const QString &actionKey));
+    MOCK_METHOD(void, actionInvoked, (qint64 id, const QString &actionKey));
+    MOCK_METHOD(void, notificationClosed, (qint64 id, uint bubbleId, uint reason));
+    MOCK_METHOD(QVariant, GetAppInfo, (const QString &appId, uint configItem));
+    MOCK_METHOD(void, removeNotification, (qint64 id));
+    MOCK_METHOD(void, removeNotifications, (const QString &appName));
+    MOCK_METHOD(void, removeNotifications, ());
+    MOCK_METHOD(void, removeExpiredNotifications, ());
+    MOCK_METHOD(void, setBlockClosedId, (qint64 id));
+};
+
</code_context>
<issue_to_address>
**suggestion (testing):** MockNotificationManager is defined but never used in the tests.

Given this rich mock interface, it’d be valuable to actually inject `MockNotificationManager` into `NotifyServerApplet` in the tests (e.g., via DI or a test-only hook) so you can assert that calls like `actionInvoked`, `notificationClosed`, and `removeNotifications` are forwarded correctly. If that wiring isn’t practical, consider removing the unused mock to avoid dead test code.
</issue_to_address>

### Comment 2
<location path="tests/panels/notification/server/notifyserverapplet_test.cpp" line_range="97-87" />
<code_context>
+}
+
+// Test memory leak detection - multiple init calls
+TEST_F(NotifyServerAppletTest, MultipleInitMemoryLeakTest) {
+    // This test checks for memory leaks when init() is called multiple times
+    // Each init() creates new NotificationManager and QThread
+    // The old ones should be properly cleaned up or prevented
+    
+    auto *testApplet = new NotifyServerApplet();
+    
+    // First init
+    testApplet->init();
+    
+    // Second init - this may create new objects without deleting old ones
+    // (Potential memory leak if not handled properly)
+    testApplet->init();
+    
+    EXPECT_NO_THROW({
+        delete testApplet;
+    });
</code_context>
<issue_to_address>
**suggestion (testing):** The NotifyServerApplet "memory leak" tests mainly check for crashes; they could exercise repeated create/init/destroy cycles more strongly.

Both `DestructorMemoryLeakTest` and `MultipleInitMemoryLeakTest` mostly verify that `init()` and destruction don’t crash. To better target the leak, consider wrapping repeated create/init/destroy cycles in a loop (e.g., 50–100 iterations) and relying on ASan/LeakSanitizer to track allocations over time, similar to the (currently commented-out) pattern in `DestructorResourceCleanupTest`. This would give stronger coverage for worker thread and manager cleanup behavior.

Suggested implementation:

```cpp
    constexpr int kIterations = 100;

    // Exercise repeated create/init/destroy cycles and rely on ASan/LSan
    // to detect leaks across iterations.
    EXPECT_NO_THROW({
        for (int i = 0; i < kIterations; ++i) {
            auto *testApplet = new NotifyServerApplet();

            testApplet->init();

            delete testApplet;
            testApplet = nullptr;
        }
    });

    // If we reach here without crash or sanitizer errors, repeated
    // create/init/destroy cycles are cleaned up correctly.
}

// Test memory leak detection - multiple init calls
TEST_F(NotifyServerAppletTest, MultipleInitMemoryLeakTest) {
    // This test checks for memory leaks when init() is called multiple times
    // on the same instance across many create/destroy cycles.
    // Each init() creates new NotificationManager and QThread; the previous
    // ones must be cleaned up properly to avoid leaks.
    constexpr int kIterations = 100;

    EXPECT_NO_THROW({
        for (int i = 0; i < kIterations; ++i) {
            auto *testApplet = new NotifyServerApplet();

            // Call init() multiple times on the same instance; if the
            // NotificationManager/QThread instances are not cleaned up
            // correctly, ASan/LeakSanitizer should report leaks.
            testApplet->init();
            testApplet->init();

            delete testApplet;
            testApplet = nullptr;
        }
    });

    // If we reach here without crash or sanitizer errors, repeated
    // multiple-init create/destroy cycles are cleaned up correctly.
}

```

If `DestructorMemoryLeakTest` previously allocated `testApplet` before the shown snippet (e.g., `auto *testApplet = new NotifyServerApplet();`), you should remove that earlier allocation to avoid an extra, now-unused instance. The new loop allocates and deletes its own instances and no longer relies on a pre-existing `testApplet`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +21 to +30
// Mock class for NotificationManager
class MockNotificationManager : public NotificationManager {
Q_OBJECT
public:
explicit MockNotificationManager(QObject *parent = nullptr)
: NotificationManager(parent) {}

MOCK_METHOD(bool, registerDbusService, (), ());
MOCK_METHOD(void, actionInvoked, (qint64 id, uint bubbleId, const QString &actionKey));
MOCK_METHOD(void, actionInvoked, (qint64 id, const QString &actionKey));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): MockNotificationManager is defined but never used in the tests.

Given this rich mock interface, it’d be valuable to actually inject MockNotificationManager into NotifyServerApplet in the tests (e.g., via DI or a test-only hook) so you can assert that calls like actionInvoked, notificationClosed, and removeNotifications are forwarded correctly. If that wiring isn’t practical, consider removing the unused mock to avoid dead test code.


// Even if init fails (e.g., D-Bus not available), we should clean up properly
// Record the state before deletion
EXPECT_NO_THROW({
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): The NotifyServerApplet "memory leak" tests mainly check for crashes; they could exercise repeated create/init/destroy cycles more strongly.

Both DestructorMemoryLeakTest and MultipleInitMemoryLeakTest mostly verify that init() and destruction don’t crash. To better target the leak, consider wrapping repeated create/init/destroy cycles in a loop (e.g., 50–100 iterations) and relying on ASan/LeakSanitizer to track allocations over time, similar to the (currently commented-out) pattern in DestructorResourceCleanupTest. This would give stronger coverage for worker thread and manager cleanup behavior.

Suggested implementation:

    constexpr int kIterations = 100;

    // Exercise repeated create/init/destroy cycles and rely on ASan/LSan
    // to detect leaks across iterations.
    EXPECT_NO_THROW({
        for (int i = 0; i < kIterations; ++i) {
            auto *testApplet = new NotifyServerApplet();

            testApplet->init();

            delete testApplet;
            testApplet = nullptr;
        }
    });

    // If we reach here without crash or sanitizer errors, repeated
    // create/init/destroy cycles are cleaned up correctly.
}

// Test memory leak detection - multiple init calls
TEST_F(NotifyServerAppletTest, MultipleInitMemoryLeakTest) {
    // This test checks for memory leaks when init() is called multiple times
    // on the same instance across many create/destroy cycles.
    // Each init() creates new NotificationManager and QThread; the previous
    // ones must be cleaned up properly to avoid leaks.
    constexpr int kIterations = 100;

    EXPECT_NO_THROW({
        for (int i = 0; i < kIterations; ++i) {
            auto *testApplet = new NotifyServerApplet();

            // Call init() multiple times on the same instance; if the
            // NotificationManager/QThread instances are not cleaned up
            // correctly, ASan/LeakSanitizer should report leaks.
            testApplet->init();
            testApplet->init();

            delete testApplet;
            testApplet = nullptr;
        }
    });

    // If we reach here without crash or sanitizer errors, repeated
    // multiple-init create/destroy cycles are cleaned up correctly.
}

If DestructorMemoryLeakTest previously allocated testApplet before the shown snippet (e.g., auto *testApplet = new NotifyServerApplet();), you should remove that earlier allocation to avoid an extra, now-unused instance. The new loop allocates and deletes its own instances and no longer relies on a pre-existing testApplet.

18202781743
18202781743 previously approved these changes Apr 21, 2026
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: heysion

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

1 similar comment
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: heysion

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@heysion heysion force-pushed the fix-rolegroupmodel-memoryleak branch 6 times, most recently from 28100cb to 7144080 Compare April 23, 2026 12:15
@heysion heysion requested a review from 18202781743 April 23, 2026 13:04
)

# fix gtest not found runpath
target_link_options(notifyserverapplet_tests PRIVATE
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这种会导致可重复编译检查出现问题吧,要是运行时报错,可以在mian里面添加library path的目录吧,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed it

@deepin-bot
Copy link
Copy Markdown

deepin-bot Bot commented Apr 23, 2026

TAG Bot

New tag: 2.0.38
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1568

@heysion heysion force-pushed the fix-rolegroupmodel-memoryleak branch 2 times, most recently from 6ac4f90 to 5c88071 Compare April 24, 2026 02:27
heysion added 11 commits April 24, 2026 10:28
Fixed memory leaks in test code by adding proper destructors and cleanup:

1. Added destructor to TestModelA to release DataA objects stored in m_list
2. Added destructor to TestModelB to release DataB objects stored in m_list
3. Fixed QAbstractItemModelTester memory leak in RoleGroupModel.ModelTest
   by adding delete statement

Also added AddressSanitizer and UndefinedBehaviorSanitizer flags to CMake
configuration for memory leak detection:
- Added -fsanitize=undefined,address to CXX_FLAGS and C_FLAGS
- Added -O0 -Wall -g -ggdb3 for debug builds
- Applied flags to both main CMakeLists.txt and tests/CMakeLists.txt

Log: Fixed memory leaks in test code and added sanitizer flags

Influence:
1. Run RoleCombineModel tests to verify no memory leaks
2. Run RoleGroupModel tests to verify QAbstractItemModelTester cleanup
3. Verify AddressSanitizer detects no leaks in test execution
4. Test that debug build works with new compiler flags
5. Verify all existing tests still pass with sanitizer enabled

fix(test): 修复测试代码中的内存泄漏

通过添加适当的析构函数和清理代码修复测试代码中的内存泄漏:

1. 为 TestModelA 添加析构函数以释放 m_list 中存储的 DataA 对象
2. 为 TestModelB 添加析构函数以释放 m_list 中存储的 DataB 对象
3. 在 RoleGroupModel.ModelTest 中添加 delete 语句修复 QAbstractItemModelTester 内存泄漏

同时向 CMake 配置添加了 AddressSanitizer 和 UndefinedBehaviorSanitizer 标志
用于内存泄漏检测:
- 向 CXX_FLAGS 和 C_FLAGS 添加 -fsanitize=undefined,address
- 添加 -O0 -Wall -g -ggdb3 用于调试构建
- 将标志应用到主 CMakeLists.txt 和 tests/CMakeLists.txt

Log: 修复测试代码内存泄漏并添加 sanitizer 标志

Influence:
1. 运行 RoleCombineModel 测试验证无内存泄漏
2. 运行 RoleGroupModel 测试验证 QAbstractItemModelTester 清理
3. 验证 AddressSanitizer 在测试执行中未检测到泄漏
4. 测试调试构建在新编译器标志下正常工作
5. 验证所有现有测试在启用 sanitizer 后仍能通过
Removed AddressSanitizer and UndefinedBehaviorSanitizer flags from
CMakeLists.txt and tests/CMakeLists.txt:
- Removed -fsanitize=undefined,address from CXX_FLAGS and C_FLAGS
- Removed -O0 -Wall -g -ggdb3 debug flags
- Removed sanitizer linker flags

These flags were temporarily added for memory leak detection during
development but are not needed in the main branch.

Log: Remove sanitizer flags from CMake configuration

Influence:
1. Verify project builds successfully without sanitizer flags
2. Check that test compilation works normally
3. Ensure no performance impact from removed debug flags

chore(build): 从 CMakeLists 中移除 sanitizer 标志

从 CMakeLists.txt 和 tests/CMakeLists.txt 中移除了 AddressSanitizer
和 UndefinedBehaviorSanitizer 标志:
- 从 CXX_FLAGS 和 C_FLAGS 中移除 -fsanitize=undefined,address
- 移除 -O0 -Wall -g -ggdb3 调试标志
- 移除 sanitizer 链接器标志

这些标志是在开发期间临时添加用于内存泄漏检测的,但在主分支中不需要。

Log: 从 CMake 配置中移除 sanitizer 标志

Influence:
1. 验证项目在没有 sanitizer 标志的情况下成功构建
2. 检查测试编译是否正常工作
3. 确保移除调试标志后没有性能影响
Added a new CMake option `ENABLE_SANITIZER` to optionally enable
AddressSanitizer and UndefinedBehaviorSanitizer for memory leak
detection and debugging purposes.

Usage:
  cmake -DENABLE_SANITIZER=ON ..

When enabled, the following flags are added:
- -fsanitize=undefined,address for both C and C++
- -O0 -Wall -g -ggdb3 for debug builds
- sanitizer linker flags

This option is OFF by default and does not affect normal builds.

Log: Add optional sanitizer support via CMake option

Influence:
1. Verify project builds normally with ENABLE_SANITIZER=OFF (default)
2. Test build with ENABLE_SANITIZER=ON to verify sanitizer works
3. Check that the option appears in cmake-gui/ccmake
4. Verify no performance impact when option is disabled

feat(build): 添加 ENABLE_SANITIZER 选项用于调试

添加了新的 CMake 选项 `ENABLE_SANITIZER`,用于可选地启用 AddressSanitizer
和 UndefinedBehaviorSanitizer 进行内存泄漏检测和调试。

使用方法:
  cmake -DENABLE_SANITIZER=ON ..

启用时会添加以下标志:
- C 和 C++ 的 -fsanitize=undefined,address
- 调试构建的 -O0 -Wall -g -ggdb3
- sanitizer 链接器标志

此选项默认关闭,不影响正常构建。

Log: 通过 CMake 选项添加可选的 sanitizer 支持

Influence:
1. 验证项目在 ENABLE_SANITIZER=OFF(默认)时正常构建
2. 测试 ENABLE_SANITIZER=ON 时 sanitizer 是否工作
3. 检查选项是否出现在 cmake-gui/ccmake 中
4. 验证选项禁用时没有性能影响
Updated SPDX-FileCopyrightText year range from "2024 - 2026" to "2026"
in notification server test files
Changed SPDX-License-Identifier from CC0-1.0 to GPL-3.0-or-later in
CMakeLists.txt to align with project licensing

Log: Update license headers and copyright year in notification tests

Influence:
1. Verify notification server tests still build correctly
2. Confirm license compatibility with project standards
3. Check copyright year consistency across test files

chore(tests): 更新许可证和版权头信息

将 SPDX-FileCopyrightText 年份范围从 "2024 - 2026" 更新为 "2026"
将 CMakeLists.txt 中的 SPDX-License-Identifier 从 CC0-1.0 更改为
GPL-3.0-or-later,以符合项目许可标准

Log: 更新通知测试中的许可证头和版权年份

Influence:
1. 验证通知服务器测试是否能正确构建
2. 确认许可证与项目标准兼容
3. 检查测试文件中版权年份的一致性
Added destructor to RoleGroupModel class to properly release resources
stored in m_map using qDeleteAll() to prevent memory leaks when the
model is destroyed

Added comprehensive memory leak test cases for RoleGroupModel:
- DestructorMemoryLeakTest: verify proper cleanup on destruction
- RebuildTreeSourceMemoryTest: test memory stability during tree rebuilds
- SetSourceModelMemoryTest: verify memory handling when switching source models
- EmptyModelMemoryTest: test boundary conditions with empty models
- LargeDataMemoryStabilityTest: stress test with large datasets
- SetDeduplicationRoleMemoryTest: verify cleanup when changing roles
- RowsInsertedMemoryTest: test memory handling on row insertion
- RowsRemovedWithEmptyGroupMemoryTest: verify cleanup when removing rows
- ModelResetMemoryTest: test memory stability during model reset

Log: Fix memory leak in RoleGroupModel with comprehensive test coverage

Influence:
1. Verify dock taskmanager functionality remains intact
2. Run memory leak tests with AddressSanitizer enabled
3. Test RoleGroupModel lifecycle scenarios
4. Validate memory cleanup in all test cases

fix(dock): 修复 RoleGroupModel 内存泄漏并添加全面测试

为 RoleGroupModel 类添加析构函数,使用 qDeleteAll() 正确释放 m_map
中存储的资源,防止模型销毁时的内存泄漏问题

添加全面的 RoleGroupModel 内存泄漏测试用例:
- DestructorMemoryLeakTest: 验证析构时的正确清理
- RebuildTreeSourceMemoryTest: 测试树重建时的内存稳定性
- SetSourceModelMemoryTest: 验证切换源模型时的内存处理
- EmptyModelMemoryTest: 测试空模型的边界条件
- LargeDataMemoryStabilityTest: 大数据集压力测试
- SetDeduplicationRoleMemoryTest: 验证角色切换时的清理
- RowsInsertedMemoryTest: 测试插入行时的内存处理
- RowsRemovedWithEmptyGroupMemoryTest: 验证删除行时的清理
- ModelResetMemoryTest: 测试模型重置时的内存稳定性

Log: 修复 RoleGroupModel 内存泄漏并添加全面测试覆盖

Influence:
1. 验证 dock 任务管理器功能保持正常
2. 启用 AddressSanitizer 运行内存泄漏测试
3. 测试 RoleGroupModel 生命周期场景
4. 验证所有测试用例的内存清理
Add libgmock-dev to Build-Depends in debian/control for gmock support

Log: Add libgmock-dev build dependency

Influence:
1. Verify package builds correctly with new dependency
2. Check gmock functionality in tests

build(debian): 添加 libgmock-dev 构建依赖

在 debian/control 的 Build-Depends 中添加 libgmock-dev 以支持 gmock

Log: 添加 libgmock-dev 构建依赖

Influence:
1. 验证软件包在新依赖下正确构建
2. 检查测试中的 gmock 功能
Updated SPDX-FileCopyrightText year format from single year to year

Log: Update copyright year ranges to reflect ongoing development

Influence:
1. Verify copyright headers display correct year ranges
2. Ensure REUSE compliance for license headers
3. Check no functional code changes introduced

chore: 更新源文件中的版权年份范围

将多个源文件中的 SPDX-FileCopyrightText 年份格式从单一年份更新为年份范围:

Log: 更新版权年份范围以反映持续开发

Influence:
1. 验证版权头显示正确的年份范围
2. 确保许可证头的 REUSE 合规性
3. 检查未引入功能性代码变更
Replaced global CMAKE_CXX_FLAGS with target-specific compile options
using target_compile_options() for better encapsulation.
Removed redundant include(GoogleTest) since find_package(GTest) is already called.

Log: Modernize CMake configuration for notification server tests

Influence:
1. Verify notifyserverapplet_tests builds successfully
2. Confirm no CMake configuration warnings

fix: 现代化通知服务器测试的 CMake 配置

使用 target_compile_options() 替代全局 CMAKE_CXX_FLAGS,
提供更好的封装性。移除冗余的 include(GoogleTest)。

Log: 现代化通知服务器测试的 CMake 配置

Influence:
1. 验证 notifyserverapplet_tests 构建成功
2. 确认没有 CMake 配置警告
When setSource() is called with the same source pointer (e.g., DBAccessor
singleton), skip the delete operation to avoid use-after-free.

Log:
@heysion heysion force-pushed the fix-rolegroupmodel-memoryleak branch from 5c88071 to 9adee5e Compare April 24, 2026 02:28
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

这份代码 diff 主要涉及内存管理优化、测试用例添加以及版权信息更新。我将从多个维度进行审查:

1. 语法逻辑

1.1 正确实现

  • 析构函数添加:在 RoleGroupModelTestModelATestModelB 中正确添加了析构函数,使用 qDeleteAll 清理容器中的指针
  • 重复设置检查DataAccessorProxy::setSource 中添加了 if (m_source == source) return; 检查,避免不必要的操作
  • 测试框架集成:正确添加了 GTest/GMock 测试框架支持

1.2 潜在问题

  • 析构函数顺序问题:在 DataAccessorProxy::setSource 中,先检查 m_source == source,但之后直接 delete m_source。如果 source 参数和 m_source 指向同一对象,可能会导致问题。建议修改为:
void DataAccessorProxy::setSource(DataAccessor *source)
{
    if (!source || m_source == source)
        return;

    if (m_source) {
        delete m_source;
        m_source = nullptr;
    }
    m_source = source;
}
  • 测试中的资源管理:在 notifyserverapplet_test.cpp 中,SetUp()TearDown() 创建/删除 QCoreApplication,但 QCoreApplication 应该只创建一次。建议使用静态初始化:
class NotifyServerAppletTest : public ::testing::Test {
protected:
    static void SetUpTestSuite() {
        if (!QCoreApplication::instance()) {
            int argc = 0;
            char *argv[] = {nullptr};
            app = new QCoreApplication(argc, argv);
        }
    }
    
    static QCoreApplication *app;
};

QCoreApplication *NotifyServerAppletTest::app = nullptr;

2. 代码质量

2.1 优点

  • 内存泄漏检测:添加了全面的内存泄漏测试用例(如 DestructorMemoryLeakTest
  • 边界条件测试:添加了多种边界情况测试(空模型、大量数据、多次初始化等)
  • 版权信息规范:统一更新了版权年份范围

2.2 改进建议

  • 测试用例注释:部分测试用例注释过多,可以精简
  • 测试命名:部分测试用例名称可以更简洁,如 SetDeduplicationRoleMemoryTest 可以改为 DeduplicationRoleChange

3. 代码性能

3.1 优化建议

  • 频繁的 qDeleteAll:在测试用例中频繁使用 qDeleteAll,对于大型测试数据集可能会影响性能。可以考虑使用对象池或智能指针
  • 信号连接测试NotificationStateChangedSignalTest 只验证信号连接存在,没有实际触发信号。建议添加:
TEST_F(NotifyServerAppletTest, NotificationStateChangedSignalEmissionTest) {
    applet->init();
    QSignalSpy spy(applet, &NotifyServerApplet::notificationStateChanged);
    
    // 触发状态变化
    // ... 具体实现取决于如何触发状态变化
    
    EXPECT_GT(spy.count(), 0);
}

4. 代码安全

4.1 安全问题

  • 空指针解引用风险:在 RoleGroupModel::~RoleGroupModel() 中直接 qDeleteAll(m_map),没有检查 m_map 是否为空。建议:
RoleGroupModel::~RoleGroupModel()
{
    if (!m_map.isEmpty()) {
        qDeleteAll(m_map);
        m_map.clear();
    }
}
  • 测试中的未初始化变量:在 notifyserverapplet_test.cpp 的多个测试用例中,initResult 变量被声明但未使用。建议:
bool initResult = testApplet->init();
ASSERT_TRUE(initResult) << "Applet initialization failed";
  • 多次初始化风险MultipleInitMemoryLeakTest 中注释掉了第二次 init() 调用,但问题未解决。建议在 NotifyServerApplet::init() 中添加保护:
bool NotifyServerApplet::init() {
    if (m_initialized) {
        qWarning() << "Applet already initialized";
        return false;
    }
    // ... 初始化代码
    m_initialized = true;
    return true;
}

4.2 资源管理

  • QThread 管理:测试中提到 init() 会创建 QThread,但没有看到明确的线程清理代码。建议在析构函数中添加:
NotifyServerApplet::~NotifyServerApplet() {
    if (m_worker) {
        m_worker->quit();
        m_worker->wait();
        delete m_worker;
    }
    // ... 其他清理
}

5. 其他建议

  1. CMakeLists.txt 改进

    • tests/panels/notification/server/CMakeLists.txt 中,建议添加编译警告选项:
    target_compile_options(notifyserverapplet_tests PRIVATE
        -Wall -Wextra -Werror
        -fvisibility=hidden
        -fvisibility-inlines-hidden
    )
  2. 测试覆盖率

    • 建议添加代码覆盖率检测工具集成(如 gcov/lcov)
  3. 内存检测工具

    • 建议在 CI/CD 中集成 ASan/Valgrind 检测,特别是针对新增的内存管理测试

总结

这份 diff 主要改进了内存管理,添加了全面的测试用例,但还存在一些潜在的安全问题和性能优化空间。建议重点关注:

  1. 完善 DataAccessorProxy::setSource 的指针检查
  2. 改进测试中的 QCoreApplication 管理
  3. 添加线程清理代码
  4. 完善初始化保护机制
  5. 集成代码覆盖率和内存检测工具

这些改进将使代码更加健壮、安全和可维护。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants