crashpad: Introduce a new SettingsReader type for read-only access [crashpad/crashpad : main]

4 views
Skip to first unread message

Joshua Pawlicki (Gerrit)

unread,
Oct 8, 2025, 4:48:55 PM (5 days ago) Oct 8
to Mark Mentovai, Crashpad LUCI CQ, crashp...@chromium.org
Attention needed from Mark Mentovai

Joshua Pawlicki voted and added 6 comments

Votes added by Joshua Pawlicki

Commit-Queue+1

6 comments

Patchset-level comments
File-level comment, Patchset 4 (Latest):
Joshua Pawlicki . unresolved

Mark, PTAL at this alternative direction to https://chromium-review.googlesource.com/c/crashpad/crashpad/+/7017459, thank you!

Unit testing is TODO pending general buy-in.

File client/settings.h
Line 122, Patchset 1: virtual bool OpenAndReadSettings(Data* out_data);
Joshua Pawlicki . resolved

Note: no attempt at locking or recovery is made in the SettingsReader; Settings overrides this to keep both behaviors.

The definition of Settings::OpenAndReadSettings is unchanged (not deleted), so it won't show up in the diff.

Line 79, Patchset 1: virtual bool Initialize();
Joshua Pawlicki . unresolved

We discussed the question of the value of Settings::Initialize over chat, the value of SettingsReader::Initialize may be an entirely separate question, but I thought the change was most clearly presented with it as an impure virtual.

Line 65, Patchset 1: explicit SettingsReader(const base::FilePath& path);
Joshua Pawlicki . unresolved

It was unclear to me whether there's value in wrapping this (plus Initialize, probably) with a unique-ptr-returning static factory function either here or in CrashReportDatabase, or whether it's just better to let the caller (O4) do a stack allocation and remember to check the return value of Initialize.

File client/settings.cc
Line 179, Patchset 1:
Joshua Pawlicki . resolved

Settings::GetLastUploadAttemptTime moved to SettingsReader::GetLastUploadAttemptTime; no diff in implementation.

Line 196, Patchset 1:
Joshua Pawlicki . resolved

Settings::ReadSettings moved to SettingsReader::ReadSettings; no diff in implementation.

Open in Gerrit

Related details

Attention is currently required from:
  • Mark Mentovai
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: crashpad/crashpad
Gerrit-Branch: main
Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
Gerrit-Change-Number: 7022792
Gerrit-PatchSet: 4
Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
Gerrit-Attention: Mark Mentovai <ma...@chromium.org>
Gerrit-Comment-Date: Wed, 08 Oct 2025 20:48:53 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
unsatisfied_requirement
open
diffy

Mark Mentovai (Gerrit)

unread,
Oct 9, 2025, 11:10:41 AM (4 days ago) Oct 9
to Joshua Pawlicki, Crashpad LUCI CQ, crashp...@chromium.org
Attention needed from Joshua Pawlicki

Mark Mentovai added 10 comments

File client/crash_report_database_generic.cc
Line 163, Patchset 6 (Latest): explicit CrashReportDatabaseGeneric(const base::FilePath& path);
Mark Mentovai . unresolved

Why is this changing?

File client/settings.h
Line 199, Patchset 6 (Latest): virtual bool OpenAndReadSettings(Data* out_data) override;
Mark Mentovai . unresolved

If you say `override`, you don’t need to also say `virtual`. I think that no Crashpad code says both together, because there’s a warning that barks at you if you do. Or at least there used to be. Even if there’s not now, be consistent.

Line 145, Patchset 6 (Latest):class Settings : public SettingsReader {
Mark Mentovai . unresolved

With the `virtual` in the mix, this class should now be `final`.

Line 136, Patchset 6 (Latest): const base::FilePath file_path_;
InitializationState initialized_;
Mark Mentovai . unresolved

Better for these to be private, and to provide protected accessors for use by the derived class.

Line 127, Patchset 6 (Latest): // |handle| must be the result of OpenForReading() or
// OpenForReadingAndWriting().
Mark Mentovai . unresolved

again, weird thing to talk about in the SettingsReader class, unless you’re also going to introduce the concept of it being overridden here.

Line 125, Patchset 6 (Latest): // failure. This does not perform recovery.
Mark Mentovai . unresolved

Recovery’s a writer concept. I don’t think this description even makes any sense here unless you introduce it.

Line 63, Patchset 6 (Latest):class SettingsReader {
Mark Mentovai . unresolved

I don’t see a way to get a SettingsReader from CrashReportDatabase, which isn’t great because the CrashReportDatabase implementation is what decides where the settings live within it.

I don’t think that means that you need a CrashReportDatabase object to get a Settings. It’s fine for there to be a separate static CrashReportDatabase::GetSettingsForDatabasePath factory. The point is that the caller should only know a database path, and shouldn’t fish around any deeper than that. A database implementation is what knows how to get Settings within.

Line 65, Patchset 1: explicit SettingsReader(const base::FilePath& path);
Joshua Pawlicki . unresolved

It was unclear to me whether there's value in wrapping this (plus Initialize, probably) with a unique-ptr-returning static factory function either here or in CrashReportDatabase, or whether it's just better to let the caller (O4) do a stack allocation and remember to check the return value of Initialize.

Mark Mentovai

It was unclear to me whether there's value in wrapping this (plus Initialize, probably) with a unique-ptr-returning static factory function either here or in CrashReportDatabase, or whether it's just better to let the caller (O4) do a stack allocation and remember to check the return value of Initialize.

If the above comment pushes things in the direction of the factory, that might help make the decision easier.

File client/settings.cc
Line 244, Patchset 6 (Latest):bool Settings::Initialize() {
Mark Mentovai . unresolved

Why did the `path` get removed from here? Just because of the inheritance? That produces a half-initialized state. I’d rather not do that.

Let’s continue doing all initialization in `Initialize`, and keep everything protected by the InitializationState object.

Line 387, Patchset 6 (Latest): ScopedLockedFileHandle handle = OpenForReading();
if (!handle.is_valid())
return false;

if (ReadSettings(handle.get(), out_data, true))
return true;
Mark Mentovai . unresolved

Can this call through to the base implementation?

Maybe not, since this seems to want to distinguish between what failed before deciding to do recovery.

Worth an explanatory comment, I guess.

Open in Gerrit

Related details

Attention is currently required from:
  • Joshua Pawlicki
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: crashpad/crashpad
Gerrit-Branch: main
Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
Gerrit-Change-Number: 7022792
Gerrit-PatchSet: 6
Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
Gerrit-Attention: Joshua Pawlicki <waf...@chromium.org>
Gerrit-Comment-Date: Thu, 09 Oct 2025 15:10:39 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Joshua Pawlicki <waf...@chromium.org>
unsatisfied_requirement
open
diffy

Joshua Pawlicki (Gerrit)

unread,
Oct 9, 2025, 11:45:27 AM (4 days ago) Oct 9
to Mark Mentovai, Crashpad LUCI CQ, crashp...@chromium.org
Attention needed from Mark Mentovai

Joshua Pawlicki added 3 comments

File client/crash_report_database_generic.cc
Line 163, Patchset 6 (Latest): explicit CrashReportDatabaseGeneric(const base::FilePath& path);
Mark Mentovai . unresolved

Why is this changing?

Joshua Pawlicki

The `_win` and `_mac` database implementations take the path in their constructors, not in Initialize. Standardizing the pattern seemed desirable.

IMO standardizing on the constructor pattern is preferable to standardizing on passing the path in Initialize, since this approach reduces mutability (i.e. base_dir_ can become const).

This is also a prerequisite to passing the settings file path to Settings::Settings, which in turn allows Settings's file_path_ member to become immutable. That's the topic of another comment thread; regardless of how that resolves I still claim having the const member makes the class easier to understand, because it's immediately clear to a reader that base_dir won't change between calls nor after initialization.

If we standardize on the `_generic` approach of taking the path in Initialize, then we should consider adding INITIALIZATION_STATE_DCHECK_VALID to DatabasePath in all of _win, _mac, _generic. While learning this code, it wasn't clear to me if there's an intentional reason we don't guard that with the same initialization state check, if the path isn't guaranteed to be correct until post-initialization.

File client/settings.h
Line 65, Patchset 1: explicit SettingsReader(const base::FilePath& path);
Joshua Pawlicki . resolved

It was unclear to me whether there's value in wrapping this (plus Initialize, probably) with a unique-ptr-returning static factory function either here or in CrashReportDatabase, or whether it's just better to let the caller (O4) do a stack allocation and remember to check the return value of Initialize.

Mark Mentovai

It was unclear to me whether there's value in wrapping this (plus Initialize, probably) with a unique-ptr-returning static factory function either here or in CrashReportDatabase, or whether it's just better to let the caller (O4) do a stack allocation and remember to check the return value of Initialize.

If the above comment pushes things in the direction of the factory, that might help make the decision easier.

Joshua Pawlicki

Yes, the above comment is a complete answer to this one.

File client/settings.cc
Line 244, Patchset 6 (Latest):bool Settings::Initialize() {
Mark Mentovai . unresolved

Why did the `path` get removed from here? Just because of the inheritance? That produces a half-initialized state. I’d rather not do that.

Let’s continue doing all initialization in `Initialize`, and keep everything protected by the InitializationState object.

Joshua Pawlicki

As mentioned above, the main benefit to passing `path` in the constructor is that the member can become `const`, which simplifies reasoning about the possibility that the member is ever modified between calls (the reader can determine that with 1 line of code read instead of having to read the entire file).

And, I also wanted to get your take on the idea of eliminating Initialize from the base class altogether, since it doesn't do anything there and is not needed.

Open in Gerrit

Related details

Attention is currently required from:
  • Mark Mentovai
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: crashpad/crashpad
Gerrit-Branch: main
Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
Gerrit-Change-Number: 7022792
Gerrit-PatchSet: 6
Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
Gerrit-Attention: Mark Mentovai <ma...@chromium.org>
Gerrit-Comment-Date: Thu, 09 Oct 2025 15:45:24 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Mark Mentovai <ma...@chromium.org>
Comment-In-Reply-To: Joshua Pawlicki <waf...@chromium.org>
unsatisfied_requirement
open
diffy

Mark Mentovai (Gerrit)

unread,
Oct 9, 2025, 12:03:00 PM (4 days ago) Oct 9
to Joshua Pawlicki, Crashpad LUCI CQ, crashp...@chromium.org
Attention needed from Joshua Pawlicki

Mark Mentovai added 3 comments

File client/crash_report_database_generic.cc
Line 163, Patchset 6 (Latest): explicit CrashReportDatabaseGeneric(const base::FilePath& path);
Mark Mentovai . resolved

Why is this changing?

Joshua Pawlicki

The `_win` and `_mac` database implementations take the path in their constructors, not in Initialize. Standardizing the pattern seemed desirable.

IMO standardizing on the constructor pattern is preferable to standardizing on passing the path in Initialize, since this approach reduces mutability (i.e. base_dir_ can become const).

This is also a prerequisite to passing the settings file path to Settings::Settings, which in turn allows Settings's file_path_ member to become immutable. That's the topic of another comment thread; regardless of how that resolves I still claim having the const member makes the class easier to understand, because it's immediately clear to a reader that base_dir won't change between calls nor after initialization.

If we standardize on the `_generic` approach of taking the path in Initialize, then we should consider adding INITIALIZATION_STATE_DCHECK_VALID to DatabasePath in all of _win, _mac, _generic. While learning this code, it wasn't clear to me if there's an intentional reason we don't guard that with the same initialization state check, if the path isn't guaranteed to be correct until post-initialization.

Mark Mentovai

The `_win` and `_mac` database implementations take the path in their constructors, not in Initialize. Standardizing the pattern seemed desirable.

IMO standardizing on the constructor pattern is preferable to standardizing on passing the path in Initialize, since this approach reduces mutability (i.e. base_dir_ can become const).

OK, that’s good enough for me.

File client/settings.cc
Line 191, Patchset 6 (Latest):bool SettingsReader::OpenAndReadSettings(Data* out_data) {
Mark Mentovai . unresolved

Call out somewhere that the base SettingsReader’s variant doesn’t participate in locking, while the derived Settings implementation does.

Line 244, Patchset 6 (Latest):bool Settings::Initialize() {
Mark Mentovai . unresolved

Why did the `path` get removed from here? Just because of the inheritance? That produces a half-initialized state. I’d rather not do that.

Let’s continue doing all initialization in `Initialize`, and keep everything protected by the InitializationState object.

Joshua Pawlicki

As mentioned above, the main benefit to passing `path` in the constructor is that the member can become `const`, which simplifies reasoning about the possibility that the member is ever modified between calls (the reader can determine that with 1 line of code read instead of having to read the entire file).

And, I also wanted to get your take on the idea of eliminating Initialize from the base class altogether, since it doesn't do anything there and is not needed.

Mark Mentovai

As mentioned above, the main benefit to passing `path` in the constructor is that the member can become `const`, which simplifies reasoning about the possibility that the member is ever modified between calls (the reader can determine that with 1 line of code read instead of having to read the entire file).

OK, assuming we go with that…

And, I also wanted to get your take on the idea of eliminating Initialize from the base class altogether, since it doesn't do anything there and is not needed.

It’s still important in the derived class, and needs to be checked by the public interfaces available from the derived class, some of which are implemented in the base.

So you can either leave it in the base (along with the quirky requirement that SettingsReader users call Initialize, even though there’s nothing to initialize), or you can wrap all of the public methods that the derived class inherits from the base with little shims that check the InitializationState before calling through to the base (which is a lot of silly boilerplate busywork).

Or you can come up with a trick where a SettingsReader that’s not a Settings somehow magically springs into existence, constructed, with a valid InitializationState, and no Initialize method at that level at all. Meanwhile, a Settings subclass has its InitializationState (living in the SettingsReader base) set to uninitialized upon construction until its (non-override) Initialize is called.

Open in Gerrit

Related details

Attention is currently required from:
  • Joshua Pawlicki
Submit Requirements:
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
  • requirement is not satisfiedNo-Unresolved-Comments
  • requirement is not satisfiedReview-Enforcement
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: crashpad/crashpad
Gerrit-Branch: main
Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
Gerrit-Change-Number: 7022792
Gerrit-PatchSet: 6
Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
Gerrit-Attention: Joshua Pawlicki <waf...@chromium.org>
Gerrit-Comment-Date: Thu, 09 Oct 2025 16:02:56 +0000
unsatisfied_requirement
open
diffy

Joshua Pawlicki (Gerrit)

unread,
Oct 10, 2025, 12:12:54 PM (3 days ago) Oct 10
to Mark Mentovai, Crashpad LUCI CQ, crashp...@chromium.org
Attention needed from Mark Mentovai

Joshua Pawlicki added 11 comments

Patchset-level comments
File-level comment, Patchset 4:
Joshua Pawlicki . resolved

Mark, PTAL at this alternative direction to https://chromium-review.googlesource.com/c/crashpad/crashpad/+/7017459, thank you!

Unit testing is TODO pending general buy-in.

Joshua Pawlicki

Done

File client/settings.h
Line 199, Patchset 6: virtual bool OpenAndReadSettings(Data* out_data) override;
Mark Mentovai . resolved

If you say `override`, you don’t need to also say `virtual`. I think that no Crashpad code says both together, because there’s a warning that barks at you if you do. Or at least there used to be. Even if there’s not now, be consistent.

Joshua Pawlicki

Done

Line 145, Patchset 6:class Settings : public SettingsReader {
Mark Mentovai . resolved

With the `virtual` in the mix, this class should now be `final`.

Joshua Pawlicki

Done

Line 136, Patchset 6: const base::FilePath file_path_;
InitializationState initialized_;
Mark Mentovai . resolved

Better for these to be private, and to provide protected accessors for use by the derived class.

Joshua Pawlicki

Done, but teach me: why is that important?

(Is it only because someone outside the project might introduce another extensions of SettingsReader, and we want to maintain flexibility to change the implementation of the accessor without breaking their code?)

Line 127, Patchset 6: // |handle| must be the result of OpenForReading() or
// OpenForReadingAndWriting().
Mark Mentovai . resolved

again, weird thing to talk about in the SettingsReader class, unless you’re also going to introduce the concept of it being overridden here.

Joshua Pawlicki

Done

Line 125, Patchset 6: // failure. This does not perform recovery.
Mark Mentovai . resolved

Recovery’s a writer concept. I don’t think this description even makes any sense here unless you introduce it.

Joshua Pawlicki

Done

Line 63, Patchset 6:class SettingsReader {
Mark Mentovai . resolved

I don’t see a way to get a SettingsReader from CrashReportDatabase, which isn’t great because the CrashReportDatabase implementation is what decides where the settings live within it.

I don’t think that means that you need a CrashReportDatabase object to get a Settings. It’s fine for there to be a separate static CrashReportDatabase::GetSettingsForDatabasePath factory. The point is that the caller should only know a database path, and shouldn’t fish around any deeper than that. A database implementation is what knows how to get Settings within.

Joshua Pawlicki

Done

Line 79, Patchset 1: virtual bool Initialize();
Joshua Pawlicki . resolved

We discussed the question of the value of Settings::Initialize over chat, the value of SettingsReader::Initialize may be an entirely separate question, but I thought the change was most clearly presented with it as an impure virtual.

Joshua Pawlicki

Done

File client/settings.cc
Line 191, Patchset 6:bool SettingsReader::OpenAndReadSettings(Data* out_data) {
Mark Mentovai . resolved

Call out somewhere that the base SettingsReader’s variant doesn’t participate in locking, while the derived Settings implementation does.

Joshua Pawlicki

Done

Line 244, Patchset 6:bool Settings::Initialize() {
Mark Mentovai . resolved

Why did the `path` get removed from here? Just because of the inheritance? That produces a half-initialized state. I’d rather not do that.

Let’s continue doing all initialization in `Initialize`, and keep everything protected by the InitializationState object.

Joshua Pawlicki

As mentioned above, the main benefit to passing `path` in the constructor is that the member can become `const`, which simplifies reasoning about the possibility that the member is ever modified between calls (the reader can determine that with 1 line of code read instead of having to read the entire file).

And, I also wanted to get your take on the idea of eliminating Initialize from the base class altogether, since it doesn't do anything there and is not needed.

Mark Mentovai

As mentioned above, the main benefit to passing `path` in the constructor is that the member can become `const`, which simplifies reasoning about the possibility that the member is ever modified between calls (the reader can determine that with 1 line of code read instead of having to read the entire file).

OK, assuming we go with that…

And, I also wanted to get your take on the idea of eliminating Initialize from the base class altogether, since it doesn't do anything there and is not needed.

It’s still important in the derived class, and needs to be checked by the public interfaces available from the derived class, some of which are implemented in the base.

So you can either leave it in the base (along with the quirky requirement that SettingsReader users call Initialize, even though there’s nothing to initialize), or you can wrap all of the public methods that the derived class inherits from the base with little shims that check the InitializationState before calling through to the base (which is a lot of silly boilerplate busywork).

Or you can come up with a trick where a SettingsReader that’s not a Settings somehow magically springs into existence, constructed, with a valid InitializationState, and no Initialize method at that level at all. Meanwhile, a Settings subclass has its InitializationState (living in the SettingsReader base) set to uninitialized upon construction until its (non-override) Initialize is called.

Joshua Pawlicki

I explored option #3 a little bit but doing template meta-programming seemed more boilerplate than option #2, and passing a "needs_initialization" bool to the constructor seemed worse than #1.

I think I do prefer #2 to #1, and implemented it in patchset 7. My theory that if there is a significant difference on behavior between Settings::Get* and SettingsReader::Get*, it's not inappropriate for Settings to encode that using an override. However, I recognize that the distinction between that point of view and the alternative interpretation that both classes check the initialization state but that "SettingsReader" is always initialized (or has to be initialized in a do-nothing method) is slight at best and I definitely don't want to get hung up on this point, so if you strongly prefer #1 we can do that.

Line 387, Patchset 6: ScopedLockedFileHandle handle = OpenForReading();

if (!handle.is_valid())
return false;

if (ReadSettings(handle.get(), out_data, true))
return true;
Mark Mentovai . resolved

Can this call through to the base implementation?

Maybe not, since this seems to want to distinguish between what failed before deciding to do recovery.

Worth an explanatory comment, I guess.

Joshua Pawlicki

Done

Open in Gerrit

Related details

Attention is currently required from:
  • Mark Mentovai
Submit Requirements:
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedReview-Enforcement
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: crashpad/crashpad
    Gerrit-Branch: main
    Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
    Gerrit-Change-Number: 7022792
    Gerrit-PatchSet: 7
    Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
    Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
    Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
    Gerrit-Attention: Mark Mentovai <ma...@chromium.org>
    Gerrit-Comment-Date: Fri, 10 Oct 2025 16:12:52 +0000
    unsatisfied_requirement
    open
    diffy

    Mark Mentovai (Gerrit)

    unread,
    Oct 10, 2025, 1:28:39 PM (3 days ago) Oct 10
    to Joshua Pawlicki, Crashpad LUCI CQ, crashp...@chromium.org
    Attention needed from Joshua Pawlicki

    Mark Mentovai added 9 comments

    File client/crash_report_database.h
    Line 277, Patchset 7 (Latest): static std::unique_ptr<SettingsReader> GetSettingsForDatabasePath(
    Mark Mentovai . unresolved

    Returns a `SettingsReader`, should be named accordingly: `GetSettingsReaderForDatabasePath`.

    Line 272, Patchset 7 (Latest): //! \param[in] path A path to the database (not the settings file). If the
    Mark Mentovai . unresolved

    This may not be obvious if you’re coming at it from the perspective of the previous revisions of this change, but it’ll be obvious as checked in.

    File client/crash_report_database_generic.cc
    Line 945, Patchset 7 (Latest):// static
    std::unique_ptr<SettingsReader> CrashReportDatabase::GetSettingsForDatabasePath(
    const base::FilePath& path) {
    return std::make_unique<SettingsReader>(path.Append(kSettings));
    }
    Mark Mentovai . unresolved

    Group with the other static factory functions defined on `CrashReportDatabase`. You may want to borrow the pattern of the _mac.cc and _win.cc files by moving those other functions down here, or you may want to move this up and make the _mac.cc and _win.cc files match.

    File client/settings.h
    Line 194, Patchset 7 (Latest): protected:
    Mark Mentovai . unresolved

    Fine, although `protected` is also pointless in a `final` class, so I wouldn’t have had a problem with you leaving this where it was while adding the `override`. It’s permissible to downgrade access to a member in a derived class.

    Line 136, Patchset 6: const base::FilePath file_path_;
    InitializationState initialized_;
    Mark Mentovai . resolved

    Better for these to be private, and to provide protected accessors for use by the derived class.

    Joshua Pawlicki

    Done, but teach me: why is that important?

    (Is it only because someone outside the project might introduce another extensions of SettingsReader, and we want to maintain flexibility to change the implementation of the accessor without breaking their code?)

    Mark Mentovai

    Done, but teach me: why is that important?

    (Is it only because someone outside the project might introduce another extensions of SettingsReader, and we want to maintain flexibility to change the implementation of the accessor without breaking their code?)

    1. Because [the style guide says so](https://google.github.io/styleguide/cppguide.html#Access_Control).

    That’s not the strongest education on its own, though, so I’ll expand:

    2. Similar to your reasoning for wanting this member to be `const`: providing a `private` member variable and a `protected` accessor but no mutator provides good assurance that the member can’t be altered outside of the base class. There are fewer places to look to assure yourself that it’s not used in surprising ways.

    File client/settings.cc
    Line 244, Patchset 6:bool Settings::Initialize() {
    Mark Mentovai . resolved

    Why did the `path` get removed from here? Just because of the inheritance? That produces a half-initialized state. I’d rather not do that.

    Let’s continue doing all initialization in `Initialize`, and keep everything protected by the InitializationState object.

    Joshua Pawlicki

    As mentioned above, the main benefit to passing `path` in the constructor is that the member can become `const`, which simplifies reasoning about the possibility that the member is ever modified between calls (the reader can determine that with 1 line of code read instead of having to read the entire file).

    And, I also wanted to get your take on the idea of eliminating Initialize from the base class altogether, since it doesn't do anything there and is not needed.

    Mark Mentovai

    As mentioned above, the main benefit to passing `path` in the constructor is that the member can become `const`, which simplifies reasoning about the possibility that the member is ever modified between calls (the reader can determine that with 1 line of code read instead of having to read the entire file).

    OK, assuming we go with that…

    And, I also wanted to get your take on the idea of eliminating Initialize from the base class altogether, since it doesn't do anything there and is not needed.

    It’s still important in the derived class, and needs to be checked by the public interfaces available from the derived class, some of which are implemented in the base.

    So you can either leave it in the base (along with the quirky requirement that SettingsReader users call Initialize, even though there’s nothing to initialize), or you can wrap all of the public methods that the derived class inherits from the base with little shims that check the InitializationState before calling through to the base (which is a lot of silly boilerplate busywork).

    Or you can come up with a trick where a SettingsReader that’s not a Settings somehow magically springs into existence, constructed, with a valid InitializationState, and no Initialize method at that level at all. Meanwhile, a Settings subclass has its InitializationState (living in the SettingsReader base) set to uninitialized upon construction until its (non-override) Initialize is called.

    Joshua Pawlicki

    I explored option #3 a little bit but doing template meta-programming seemed more boilerplate than option #2, and passing a "needs_initialization" bool to the constructor seemed worse than #1.

    I think I do prefer #2 to #1, and implemented it in patchset 7. My theory that if there is a significant difference on behavior between Settings::Get* and SettingsReader::Get*, it's not inappropriate for Settings to encode that using an override. However, I recognize that the distinction between that point of view and the alternative interpretation that both classes check the initialization state but that "SettingsReader" is always initialized (or has to be initialized in a do-nothing method) is slight at best and I definitely don't want to get hung up on this point, so if you strongly prefer #1 we can do that.

    Mark Mentovai

    I explored option #3 a little bit but doing template meta-programming seemed more boilerplate than option #2, and passing a "needs_initialization" bool to the constructor seemed worse than #1.

    Template meta-programming? Oh my!

    Here’s what I had in mind:

    ```
    class SettingsReader {
    public:
    explicit Settings(FilePath const& path)
    : Settings(path, InitializationSate::kStateValid) {}
     protected:
    Settings(FilePath const& path, InitializationState::State state)
    : path_(path), state_(state) {}
    };
    class Settings : public SettingsReader {
    public:
    explicit Settings(FilePath const&)
    : SettingsReader(path, InitializationState::kStateUninitialized) {}
    };
    ```

    As implemented in patch set 7, the additional boilerplate which would need to be implemented for any future extensions to this class is uncomfortably easy to miss. Patch set 7 is also more `virtual` bloat without strong justification.

    File client/settings_test.cc
    Line 123, Patchset 7 (Latest): EXPECT_TRUE(reader.GetUploadsEnabled(&enabled));
    Mark Mentovai . resolved

    I’d normally ask for `ASSERT_TRUE` but I see that this is done elsewhere in this test, and it’s always `EXPECT_TRUE`. I can also find other cases where `ASSERT_TRUE` should have been used, such as around `Initialize` calls.

    No need to clean all of this up now. You can do this to match the (imperfect) surroundings.

    Line 133, Patchset 7 (Latest): EXPECT_TRUE(enabled); // Not modified.
    Mark Mentovai . unresolved

    There’s no documented interface requirement to not touch or touch this, so there’s no reason to test it.

    Line 135, Patchset 7 (Latest):}
    Mark Mentovai . unresolved

    You also need to test that settings modified by the derived `Settings` class are properly read by the base `SettingsReader`. You don’t have to test every property, but it would be good to test `GetUploadsEnabled` as above, since that’s what you’re interested in using.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Joshua Pawlicki
    Submit Requirements:
      • requirement is not satisfiedCode-Owners
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: crashpad/crashpad
      Gerrit-Branch: main
      Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
      Gerrit-Change-Number: 7022792
      Gerrit-PatchSet: 7
      Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
      Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
      Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
      Gerrit-Attention: Joshua Pawlicki <waf...@chromium.org>
      Gerrit-Comment-Date: Fri, 10 Oct 2025 17:28:36 +0000
      unsatisfied_requirement
      open
      diffy

      Mark Mentovai (Gerrit)

      unread,
      Oct 10, 2025, 1:29:06 PM (3 days ago) Oct 10
      to Joshua Pawlicki, Crashpad LUCI CQ, crashp...@chromium.org
      Attention needed from Joshua Pawlicki

      Mark Mentovai added 1 comment

      File client/settings.cc
      Line 244, Patchset 6:bool Settings::Initialize() {
      Mark Mentovai . unresolved

      Related details

      Attention is currently required from:
      • Joshua Pawlicki
      Submit Requirements:
      • requirement is not satisfiedCode-Owners
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      • requirement is not satisfiedReview-Enforcement
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: crashpad/crashpad
      Gerrit-Branch: main
      Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
      Gerrit-Change-Number: 7022792
      Gerrit-PatchSet: 7
      Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
      Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
      Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
      Gerrit-Attention: Joshua Pawlicki <waf...@chromium.org>
      Gerrit-Comment-Date: Fri, 10 Oct 2025 17:29:04 +0000
      unsatisfied_requirement
      open
      diffy

      Joshua Pawlicki (Gerrit)

      unread,
      Oct 10, 2025, 2:29:26 PM (3 days ago) Oct 10
      to Mark Mentovai, Crashpad LUCI CQ, crashp...@chromium.org
      Attention needed from Mark Mentovai

      Joshua Pawlicki added 7 comments

      File client/crash_report_database.h
      Line 277, Patchset 7: static std::unique_ptr<SettingsReader> GetSettingsForDatabasePath(
      Mark Mentovai . resolved

      Returns a `SettingsReader`, should be named accordingly: `GetSettingsReaderForDatabasePath`.

      Joshua Pawlicki

      Done

      Line 272, Patchset 7: //! \param[in] path A path to the database (not the settings file). If the
      Mark Mentovai . resolved

      This may not be obvious if you’re coming at it from the perspective of the previous revisions of this change, but it’ll be obvious as checked in.

      Joshua Pawlicki

      Done

      File client/crash_report_database_generic.cc

      std::unique_ptr<SettingsReader> CrashReportDatabase::GetSettingsForDatabasePath(
      const base::FilePath& path) {
      return std::make_unique<SettingsReader>(path.Append(kSettings));
      }
      Mark Mentovai . resolved

      Group with the other static factory functions defined on `CrashReportDatabase`. You may want to borrow the pattern of the _mac.cc and _win.cc files by moving those other functions down here, or you may want to move this up and make the _mac.cc and _win.cc files match.

      Joshua Pawlicki

      Done

      File client/settings.h
      Line 194, Patchset 7: protected:
      Mark Mentovai . resolved

      Fine, although `protected` is also pointless in a `final` class, so I wouldn’t have had a problem with you leaving this where it was while adding the `override`. It’s permissible to downgrade access to a member in a derived class.

      Joshua Pawlicki

      Done

      File client/settings.cc
      Line 244, Patchset 6:bool Settings::Initialize() {
      Mark Mentovai . resolved
      Joshua Pawlicki

      Ah, I didn't think of using a protected constructor, just the public one. Done.

      File client/settings_test.cc
      Line 133, Patchset 7: EXPECT_TRUE(enabled); // Not modified.
      Mark Mentovai . resolved

      There’s no documented interface requirement to not touch or touch this, so there’s no reason to test it.

      Joshua Pawlicki

      Done

      Line 135, Patchset 7:}
      Mark Mentovai . resolved

      You also need to test that settings modified by the derived `Settings` class are properly read by the base `SettingsReader`. You don’t have to test every property, but it would be good to test `GetUploadsEnabled` as above, since that’s what you’re interested in using.

      Joshua Pawlicki

      Done

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Mark Mentovai
      Submit Requirements:
        • requirement is not satisfiedCode-Owners
        • requirement is not satisfiedCode-Review
        • requirement is not satisfiedReview-Enforcement
        Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
        Gerrit-MessageType: comment
        Gerrit-Project: crashpad/crashpad
        Gerrit-Branch: main
        Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
        Gerrit-Change-Number: 7022792
        Gerrit-PatchSet: 7
        Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
        Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
        Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
        Gerrit-Attention: Mark Mentovai <ma...@chromium.org>
        Gerrit-Comment-Date: Fri, 10 Oct 2025 18:29:24 +0000
        unsatisfied_requirement
        open
        diffy

        Mark Mentovai (Gerrit)

        unread,
        Oct 10, 2025, 2:52:37 PM (3 days ago) Oct 10
        to Joshua Pawlicki, Crashpad LUCI CQ, crashp...@chromium.org
        Attention needed from Joshua Pawlicki

        Mark Mentovai added 7 comments

        Patchset-level comments
        File-level comment, Patchset 8 (Latest):
        Mark Mentovai . resolved

        This is in very good shape now. Thanks, Joshua!

        Line 914, Patchset 8 (Latest):std::unique_ptr<CrashReportDatabase> InitializeInternal(
        Mark Mentovai . unresolved

        So this is just `crashpad::InitializeInternal`? That’s not right.

        You don’t have to deal with it here if you don’t want to, but can you fix it in a follow-up?

        You also don’t have to do that if you don’t want to. In that case, just say so, and I’ll do it.

        The easiest way to fix this would be to wrap it in an unnamed namespace.

        Same in _win.cc.

        File client/crash_report_database_win.cc
        Line 913, Patchset 8 (Latest):std::unique_ptr<CrashReportDatabase> InitializeInternal(
        Mark Mentovai . unresolved

        (looking here because of the previous comment—the same commentary about when to fix and who should fix applies here too.)

        This is in the middle of nowhere now, and seemingly should also move down.

        File client/settings.h
        Line 149, Patchset 8 (Latest): Settings(const base::FilePath& file_path);
        Mark Mentovai . unresolved

        `explicit`

        Line 82, Patchset 8 (Latest): virtual bool GetClientID(UUID* client_id);
        Mark Mentovai . unresolved

        This isn’t overriden, so it no longer needs to be `virtual`. The same applies to the 2 other `Get*` methods.

        Line 65, Patchset 8 (Parent)://! This class must not be instantiated directly, but rather an instance of it
        //! should be retrieved via CrashReportDatabase::GetSettings().
        Mark Mentovai . unresolved

        We had this nice comment telling people not to create these objects directly on their own, but to get them from the database. We still have that for `Settings`, it’s just moved down a bit in the file.

        We should have a similar comment for `SettingsReader`, referring to the new function you added in `CrashReportDatabase`.

        File client/settings.cc
        Line 156, Patchset 8 (Latest): DCHECK(initialized().is_valid());
        Mark Mentovai . unresolved

        Leave a blank line after the `DCHECK`, the same way that the old code used to, in all 3 `Get*` methods. Separating the preconditions from the rest of the code helps break up the flow and makes it easier to read. It might also encourage a better diff and better future blame.

        Open in Gerrit

        Related details

        Attention is currently required from:
        • Joshua Pawlicki
        Submit Requirements:
          • requirement is not satisfiedCode-Owners
          • requirement is not satisfiedCode-Review
          • requirement is not satisfiedNo-Unresolved-Comments
          • requirement is not satisfiedReview-Enforcement
          Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
          Gerrit-MessageType: comment
          Gerrit-Project: crashpad/crashpad
          Gerrit-Branch: main
          Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
          Gerrit-Change-Number: 7022792
          Gerrit-PatchSet: 8
          Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
          Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
          Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
          Gerrit-Attention: Joshua Pawlicki <waf...@chromium.org>
          Gerrit-Comment-Date: Fri, 10 Oct 2025 18:52:35 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: No
          unsatisfied_requirement
          open
          diffy

          Joshua Pawlicki (Gerrit)

          unread,
          Oct 10, 2025, 3:09:42 PM (3 days ago) Oct 10
          to Mark Mentovai, Crashpad LUCI CQ, crashp...@chromium.org
          Attention needed from Mark Mentovai

          Joshua Pawlicki added 6 comments

          Line 914, Patchset 8:std::unique_ptr<CrashReportDatabase> InitializeInternal(
          Mark Mentovai . resolved

          So this is just `crashpad::InitializeInternal`? That’s not right.

          You don’t have to deal with it here if you don’t want to, but can you fix it in a follow-up?

          You also don’t have to do that if you don’t want to. In that case, just say so, and I’ll do it.

          The easiest way to fix this would be to wrap it in an unnamed namespace.

          Same in _win.cc.

          Joshua Pawlicki

          Done; I previously wondered if the entire CrashReportDatabaseMac could/should be moved into an anonymous namespace, which could possibly help a little bit with clarity and might reduce the chance of this kind of mistake in the future, but I didn't go there in this patch set.

          File client/crash_report_database_win.cc
          Line 913, Patchset 8:std::unique_ptr<CrashReportDatabase> InitializeInternal(
          Mark Mentovai . resolved

          (looking here because of the previous comment—the same commentary about when to fix and who should fix applies here too.)

          This is in the middle of nowhere now, and seemingly should also move down.

          Joshua Pawlicki

          Done

          File client/settings.h
          Line 149, Patchset 8: Settings(const base::FilePath& file_path);
          Mark Mentovai . resolved

          `explicit`

          Joshua Pawlicki

          Done

          Line 82, Patchset 8: virtual bool GetClientID(UUID* client_id);
          Mark Mentovai . resolved

          This isn’t overriden, so it no longer needs to be `virtual`. The same applies to the 2 other `Get*` methods.

          Joshua Pawlicki

          Good point, forgot to remove those. Done.

          Line 65, Patchset 8 (Parent)://! This class must not be instantiated directly, but rather an instance of it
          //! should be retrieved via CrashReportDatabase::GetSettings().
          Mark Mentovai . resolved

          We had this nice comment telling people not to create these objects directly on their own, but to get them from the database. We still have that for `Settings`, it’s just moved down a bit in the file.

          We should have a similar comment for `SettingsReader`, referring to the new function you added in `CrashReportDatabase`.

          Joshua Pawlicki

          Yeah, I wondered if it would come up. I previously struggled a little bit with it, specifically the "must not". Obviously, the tests instantiate it directly, as does the derived class. So I had left it off.

          I took a stab at a new comment, LMK if you think it's short of the mark.

          File client/settings.cc
          Line 156, Patchset 8: DCHECK(initialized().is_valid());
          Mark Mentovai . resolved

          Leave a blank line after the `DCHECK`, the same way that the old code used to, in all 3 `Get*` methods. Separating the preconditions from the rest of the code helps break up the flow and makes it easier to read. It might also encourage a better diff and better future blame.

          Joshua Pawlicki

          Done

          Open in Gerrit

          Related details

          Attention is currently required from:
          • Mark Mentovai
          Submit Requirements:
            • requirement is not satisfiedCode-Owners
            • requirement is not satisfiedCode-Review
            • requirement is not satisfiedReview-Enforcement
            Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
            Gerrit-MessageType: comment
            Gerrit-Project: crashpad/crashpad
            Gerrit-Branch: main
            Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
            Gerrit-Change-Number: 7022792
            Gerrit-PatchSet: 8
            Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
            Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
            Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
            Gerrit-Attention: Mark Mentovai <ma...@chromium.org>
            Gerrit-Comment-Date: Fri, 10 Oct 2025 19:09:39 +0000
            Gerrit-HasComments: Yes
            Gerrit-Has-Labels: No
            Comment-In-Reply-To: Mark Mentovai <ma...@chromium.org>
            unsatisfied_requirement
            open
            diffy

            Mark Mentovai (Gerrit)

            unread,
            Oct 10, 2025, 4:28:21 PM (3 days ago) Oct 10
            to Joshua Pawlicki, Crashpad LUCI CQ, crashp...@chromium.org
            Attention needed from Joshua Pawlicki

            Mark Mentovai added 2 comments

            Line 914, Patchset 8:std::unique_ptr<CrashReportDatabase> InitializeInternal(
            Mark Mentovai . resolved

            So this is just `crashpad::InitializeInternal`? That’s not right.

            You don’t have to deal with it here if you don’t want to, but can you fix it in a follow-up?

            You also don’t have to do that if you don’t want to. In that case, just say so, and I’ll do it.

            The easiest way to fix this would be to wrap it in an unnamed namespace.

            Same in _win.cc.

            Joshua Pawlicki

            Done; I previously wondered if the entire CrashReportDatabaseMac could/should be moved into an anonymous namespace, which could possibly help a little bit with clarity and might reduce the chance of this kind of mistake in the future, but I didn't go there in this patch set.

            Mark Mentovai

            Done; I previously wondered if the entire CrashReportDatabaseMac could/should be moved into an anonymous namespace, which could possibly help a little bit with clarity and might reduce the chance of this kind of mistake in the future, but I didn't go there in this patch set.

            It could, and doing so would be very much in line with Crashpad style. Same for the `…Generic` and `…Win` implementations.

            I think the `friend` declarations in the client/crash_report_database.h are the reason that these classes aren’t in unnamed namespaces.

            File client/settings.h
            Line 66, Patchset 9 (Latest)://! Prefer to construct this instances of this class through
            //! CrashReportDatabase::GetSettingsReaderForDatabasePath.
            Mark Mentovai . unresolved

            Please strengthen this in line with the admonition in Settings.

            This doesn’t provide guidance for a unit test. A unit test is implicitly permitted exceed the limits established by the documentation. The existing unit test for `Settings` already overcame the documented perimeter, instantiating and initializing its own `Settings` objects without touching `CrashReportDatabase`.

            This particular instance of inheritance also involves a close coupling, and the inheritance an implementation detail, so in that regard, the comment doesn’t apply.

            In general, read (and write!) these public interface comments as a users’ manual, not an implementers’ manual.

            Open in Gerrit

            Related details

            Attention is currently required from:
            • Joshua Pawlicki
            Submit Requirements:
              • requirement is not satisfiedCode-Owners
              • requirement is not satisfiedCode-Review
              • requirement is not satisfiedNo-Unresolved-Comments
              • requirement is not satisfiedReview-Enforcement
              Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
              Gerrit-MessageType: comment
              Gerrit-Project: crashpad/crashpad
              Gerrit-Branch: main
              Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
              Gerrit-Change-Number: 7022792
              Gerrit-PatchSet: 9
              Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
              Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
              Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
              Gerrit-Attention: Joshua Pawlicki <waf...@chromium.org>
              Gerrit-Comment-Date: Fri, 10 Oct 2025 20:28:19 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: No
              Comment-In-Reply-To: Mark Mentovai <ma...@chromium.org>
              Comment-In-Reply-To: Joshua Pawlicki <waf...@chromium.org>
              unsatisfied_requirement
              open
              diffy

              Joshua Pawlicki (Gerrit)

              unread,
              Oct 10, 2025, 5:03:13 PM (3 days ago) Oct 10
              to Mark Mentovai, Crashpad LUCI CQ, crashp...@chromium.org
              Attention needed from Mark Mentovai

              Joshua Pawlicki added 1 comment

              File client/settings.h
              Line 66, Patchset 9://! Prefer to construct this instances of this class through
              //! CrashReportDatabase::GetSettingsReaderForDatabasePath.
              Mark Mentovai . resolved

              Please strengthen this in line with the admonition in Settings.

              This doesn’t provide guidance for a unit test. A unit test is implicitly permitted exceed the limits established by the documentation. The existing unit test for `Settings` already overcame the documented perimeter, instantiating and initializing its own `Settings` objects without touching `CrashReportDatabase`.

              This particular instance of inheritance also involves a close coupling, and the inheritance an implementation detail, so in that regard, the comment doesn’t apply.

              In general, read (and write!) these public interface comments as a users’ manual, not an implementers’ manual.

              Joshua Pawlicki

              Done

              Open in Gerrit

              Related details

              Attention is currently required from:
              • Mark Mentovai
              Submit Requirements:
                • requirement is not satisfiedCode-Owners
                • requirement is not satisfiedCode-Review
                • requirement is not satisfiedReview-Enforcement
                Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                Gerrit-MessageType: comment
                Gerrit-Project: crashpad/crashpad
                Gerrit-Branch: main
                Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
                Gerrit-Change-Number: 7022792
                Gerrit-PatchSet: 9
                Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
                Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
                Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
                Gerrit-Attention: Mark Mentovai <ma...@chromium.org>
                Gerrit-Comment-Date: Fri, 10 Oct 2025 21:03:11 +0000
                unsatisfied_requirement
                open
                diffy

                Mark Mentovai (Gerrit)

                unread,
                Oct 10, 2025, 5:05:31 PM (3 days ago) Oct 10
                to Joshua Pawlicki, Crashpad LUCI CQ, crashp...@chromium.org
                Attention needed from Joshua Pawlicki

                Mark Mentovai voted and added 1 comment

                Votes added by Mark Mentovai

                Code-Review+1

                1 comment

                Patchset-level comments
                File-level comment, Patchset 10 (Latest):
                Mark Mentovai . resolved

                Thanks for approaching this in a try-it-and-see, refine-as-you-go iterative process. I’m happy with where we wound up on this.

                Open in Gerrit

                Related details

                Attention is currently required from:
                • Joshua Pawlicki
                Submit Requirements:
                • requirement satisfiedCode-Owners
                • requirement satisfiedCode-Review
                • requirement satisfiedReview-Enforcement
                Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                Gerrit-MessageType: comment
                Gerrit-Project: crashpad/crashpad
                Gerrit-Branch: main
                Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
                Gerrit-Change-Number: 7022792
                Gerrit-PatchSet: 10
                Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
                Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
                Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
                Gerrit-Attention: Joshua Pawlicki <waf...@chromium.org>
                Gerrit-Comment-Date: Fri, 10 Oct 2025 21:05:27 +0000
                Gerrit-HasComments: Yes
                Gerrit-Has-Labels: Yes
                satisfied_requirement
                open
                diffy

                Joshua Pawlicki (Gerrit)

                unread,
                Oct 10, 2025, 5:08:17 PM (3 days ago) Oct 10
                to Mark Mentovai, Crashpad LUCI CQ, crashp...@chromium.org

                Joshua Pawlicki added 1 comment

                Patchset-level comments
                Mark Mentovai . resolved

                Thanks for approaching this in a try-it-and-see, refine-as-you-go iterative process. I’m happy with where we wound up on this.

                Joshua Pawlicki

                👍

                Open in Gerrit

                Related details

                Attention set is empty
                Submit Requirements:
                • requirement satisfiedCode-Owners
                • requirement satisfiedCode-Review
                • requirement satisfiedReview-Enforcement
                Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                Gerrit-MessageType: comment
                Gerrit-Project: crashpad/crashpad
                Gerrit-Branch: main
                Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
                Gerrit-Change-Number: 7022792
                Gerrit-PatchSet: 10
                Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
                Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
                Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
                Gerrit-Comment-Date: Fri, 10 Oct 2025 21:08:15 +0000
                satisfied_requirement
                open
                diffy

                Joshua Pawlicki (Gerrit)

                unread,
                Oct 10, 2025, 5:08:22 PM (3 days ago) Oct 10
                to Mark Mentovai, Crashpad LUCI CQ, crashp...@chromium.org

                Joshua Pawlicki voted Commit-Queue+2

                Commit-Queue+2
                Open in Gerrit

                Related details

                Attention set is empty
                Submit Requirements:
                • requirement satisfiedCode-Owners
                • requirement satisfiedCode-Review
                • requirement satisfiedReview-Enforcement
                Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                Gerrit-MessageType: comment
                Gerrit-Project: crashpad/crashpad
                Gerrit-Branch: main
                Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
                Gerrit-Change-Number: 7022792
                Gerrit-PatchSet: 10
                Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
                Gerrit-Reviewer: Joshua Pawlicki <waf...@chromium.org>
                Gerrit-Reviewer: Mark Mentovai <ma...@chromium.org>
                Gerrit-Comment-Date: Fri, 10 Oct 2025 21:08:19 +0000
                Gerrit-HasComments: No
                Gerrit-Has-Labels: Yes
                satisfied_requirement
                open
                diffy

                Crashpad LUCI CQ (Gerrit)

                unread,
                Oct 10, 2025, 5:12:50 PM (3 days ago) Oct 10
                to Joshua Pawlicki, Mark Mentovai, crashp...@chromium.org

                Crashpad LUCI CQ submitted the change

                Change information

                Commit message:
                crashpad: Introduce a new SettingsReader type for read-only access
                Bug: 448113221
                Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
                Reviewed-by: Mark Mentovai <ma...@chromium.org>
                Commit-Queue: Joshua Pawlicki <waf...@chromium.org>
                Files:
                • M client/crash_report_database.h
                • M client/crash_report_database_generic.cc
                • M client/crash_report_database_mac.mm
                • M client/crash_report_database_win.cc
                • M client/settings.cc
                • M client/settings.h
                • M client/settings_test.cc
                • M util/misc/initialization_state.h
                Change size: L
                Delta: 8 files changed, 291 insertions(+), 197 deletions(-)
                Branch: refs/heads/main
                Submit Requirements:
                • requirement satisfiedCode-Review: +1 by Mark Mentovai
                Open in Gerrit
                Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
                Gerrit-MessageType: merged
                Gerrit-Project: crashpad/crashpad
                Gerrit-Branch: main
                Gerrit-Change-Id: I0e7bc9513fdbc1c22b3d94a82efeb0adee6cb04c
                Gerrit-Change-Number: 7022792
                Gerrit-PatchSet: 11
                Gerrit-Owner: Joshua Pawlicki <waf...@chromium.org>
                Gerrit-Reviewer: Crashpad LUCI CQ <crashpa...@luci-project-accounts.iam.gserviceaccount.com>
                open
                diffy
                satisfied_requirement
                Reply all
                Reply to author
                Forward
                0 new messages