Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

memory leaks fixes in non-gui tests #1213

Merged
merged 1 commit into from
Nov 27, 2017

Conversation

michalkaptur
Copy link
Contributor

@michalkaptur michalkaptur commented Nov 22, 2017

Fixed memory leaks non-gui tests

Description

Fixed 2 memory leaks in production code and a few in testcases. As a result leak_check_at_exit ASAN option does not need to turned off for non-gui tests.
Smart pointers should be used elsewhere for consistency, but the sooner this fixes are delivered, the lesser memory leaks are introduced.

Motivation and context

Memory leaks are bugs in short, so motivation is pretty straightforward :)

How has this been tested?

No logic was altered, thus existing testcases are sufficient

Screenshots (if appropriate):

Types of changes

  • ✅ Bug fix (non-breaking change which fixes an issue)

Checklist:

  • ✅ I have read the CONTRIBUTING document. [REQUIRED]
  • ✅ My code follows the code style of this project. [REQUIRED]
  • ✅ All new and existing tests passed. [REQUIRED]
  • ✅ I have compiled and verified my code with -DWITH_ASAN=ON. [REQUIRED]

@adolfogc
Copy link
Contributor

@michalkaptur For consistency with the rest of the codebase, I think it would it be better to use QScopedPointer instead of std::unique_ptr.

@phoerious
Copy link
Member

I was about to suggest the same. Not for consistency, but for safety reasons. Don't use STL smart pointers, though. Use Qt smartpointers.

Copy link
Member

@phoerious phoerious left a comment

Choose a reason for hiding this comment

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

Nice findings. Thanks for sharing them! You should use QScopedPointers, though.

@@ -49,7 +49,7 @@ class SymmetricCipherGcrypt : public SymmetricCipherBackend
static int gcryptMode(SymmetricCipher::Mode mode);
void setErrorString(gcry_error_t err);

gcry_cipher_hd_t m_ctx;
gcry_cipher_hd_t m_ctx{nullptr};
Copy link
Member

Choose a reason for hiding this comment

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

This is redundant. m_ctx is already initialized to nullptr within the initialization list of the constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@@ -29,8 +29,14 @@ KeePass2Repair::KeePass2Repair()
{
}

KeePass2Repair::~KeePass2Repair()
{
delete m_db;
Copy link
Member

Choose a reason for hiding this comment

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

Make m_db a QScopedPointer and remove this code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

KeePass2Repair::RepairResult KeePass2Repair::repairDatabase(QIODevice* device, const CompositeKey& key)
{
delete m_db;
Copy link
Member

@phoerious phoerious Nov 22, 2017

Choose a reason for hiding this comment

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

Call

m_db.reset(reader.readDatabase(device, key, true));

instead. Replace further deletions of m_db within this file with QScopedPointer::reset() as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done, but kept temporary db object not to store the database after repair failed

@@ -63,7 +63,7 @@ private slots:

private:
QTemporaryFile* file;
Copy link
Member

Choose a reason for hiding this comment

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

Make this a QScopedPointer

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -63,7 +63,7 @@ private slots:

private:
QTemporaryFile* file;
CsvParser* parser;
std::unique_ptr<CsvParser> parser;
Copy link
Member

Choose a reason for hiding this comment

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

And this as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -339,7 +340,7 @@ void TestGroup::testCopyCustomIcon()

void TestGroup::testClone()
{
Database* db = new Database();
std::unique_ptr<Database> db(new Database());
Copy link
Member

@phoerious phoerious Nov 23, 2017

Choose a reason for hiding this comment

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

Replace all std::unique_ptrs in this file with QScopedPointers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done, replaced all

@phoerious
Copy link
Member

Could you also retarget this at release/2.2.3? Thanks!

@phoerious phoerious added this to the v2.2.3 milestone Nov 23, 2017
@phoerious phoerious added the bug label Nov 23, 2017
@adolfogc
Copy link
Contributor

Not for consistency, but for safety reasons.

@phoerious Why is it safer to use Qt's smartpointers than STL's?

@phoerious
Copy link
Member

phoerious commented Nov 23, 2017

I think I just read you slightly wrong there. The safety part is about using smart pointers over raw pointers. I somehow read that you would choose smart pointers in general for consistency. Choosing Qt smart pointers over the STL ones is of course just about consistency. 😉

@michalkaptur
Copy link
Contributor Author

Ok, I'll replace the std::unique_ptrs with QScopedPointerfor consistency and fix review remarks in the evening.
On the other hand, is it a more general rule for this project to use Qt library over std, even if the code is separated from Qt gui parts?

@phoerious
Copy link
Member

Yes, use Qt classes where possible. Qt is not just a GUI toolkit.

@michalkaptur
Copy link
Contributor Author

Qt is not just a GUI toolkit.

Definitely.

use Qt classes where possible

I'm more like "use std wherever possible", but for the sake of consistency - I'll adapt :)

@phoerious
Copy link
Member

Qt and STL are mostly compatible, but not 100%.They also have two very distinct coding styles. Using Qt everywhere keeps the code consistent and prevents any compatibility problems from the start. I don't think we use STL containers or algorithms anywhere in KeePassXC

{
return m_db;
return m_db.take();
Copy link
Member

Choose a reason for hiding this comment

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

Sorry to nag again, but I didn't see that you need to share ownership of the pointer. In this case, this should be a QSharedPointer instead of a QScopedPointer.
This method should stay const and return the QSharedPointer instead of a raw pointer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, but I wanted to leave DatabaseOpenWidget intact for now.

Copy link
Member

Choose a reason for hiding this comment

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

If we change something, we should do it properly from the start.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, got it. My goal was to enable leak_check_at_exit ASAN check for non-gui tests, without breaking too many interfaces, and then work on other memory management issues.
Considering shared ownership: There's actually no need for KeePass2Repair to store the database (pointer, to be exact). What do you think about returning a tuple from repairDatabase(), consisting of RepairResult and Database*?

Copy link
Member

Choose a reason for hiding this comment

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

I understand that. I would do the same. But KeePassXC has inherited quite some baggage from KeePassX that needs cleaning up, so in cases like this we should do things properly instead of producing more patchwork.
I had a deeper look into the repair class and agree with you: there is no need to store the database. Returning a QPair<RepairResult, QSharedPointer<Database>> sounds like a decent solution to me.

While you are at it could you also please add

Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>

to the license headers? This is missing somehow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, thanks for assistance and understanding :) I've just pushed fixed KeePass2Repair. Just to be clear: should this PR be merged to release/2.2.2 branch only or to both, develop and release/2.2.2? I'm not familiar with release/branching policy yet.

Copy link
Member

Choose a reason for hiding this comment

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

Only to release/2.2.3 (not 2.2.2). That branch will be merged back into develop then. Just rebase against it and change the target of this PR, I'll take care of the rest.
I hope you also don't mind if I squash your commits into one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm a bit stuck in leaky TestGroup.cpp unit tests after rebase. I'll deliver it soon.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, the changes are rebased against release/2.2.3, squashed and green on CI 😃

Copy link
Member

Choose a reason for hiding this comment

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

Thanks!

QString errorString() const;

private:
Database* m_db;
QScopedPointer<Database> m_db{nullptr};
Copy link
Member

Choose a reason for hiding this comment

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

You should initialize members in the initialization list of the constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why do you think so? User defined constructors for member default initialization only are considered not-the-best practice: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rc-in-class-initializer

Copy link
Member

Choose a reason for hiding this comment

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

For consistency reasons. But if you must initialize things like this, at least use the assignment syntax.
In this case, however, you could (and should) skip initialization completely, which will default-initialize the smart pointer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree, QScopedPointer is initialized to Q_NULLPTR by default. Fixed

Fixed 2 memory leaks in production code and a few in testcases. As a
result leak_check_at_exit ASAN option does not need to turned off for
non-gui tests.
Smart pointers should be used elsewhere for consistency, but the sooner
this fixes are delivered, the lesser memory leaks are introduced.
@michalkaptur michalkaptur changed the base branch from develop to release/2.2.3 November 27, 2017 22:09
@phoerious phoerious merged commit 0ff75e7 into keepassxreboot:release/2.2.3 Nov 27, 2017
droidmonkey added a commit that referenced this pull request Dec 12, 2017
- Prevent database corruption when locked [#1219]
- Fixes apply button not saving new entries [#1141]
- Switch to Consolas font on Windows for password edit [#1229]
- Multiple fixes to AppImage deployment [#1115, #1228]
- Fixes multiple memory leaks [#1213]
- Resize message close to 16x16 pixels [#1253]
phoerious added a commit that referenced this pull request Dec 13, 2017
- Prevent database corruption when locked [#1219]
- Fixes apply button not saving new entries [#1141]
- Switch to Consolas font on Windows for password edit [#1229]
- Multiple fixes to AppImage deployment [#1115, #1228]
- Fixes multiple memory leaks [#1213]
- Resize message close to 16x16 pixels [#1253]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants