2014-08-14 09:51:26 -07:00
|
|
|
|
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
|
|
#ifndef CRASHPAD_UTIL_MISC_INITIALIZATION_INITIALIZATION_STATE_DCHECK_H_
|
|
|
|
|
#define CRASHPAD_UTIL_MISC_INITIALIZATION_INITIALIZATION_STATE_DCHECK_H_
|
|
|
|
|
|
|
|
|
|
//! \file
|
|
|
|
|
|
2015-02-11 13:39:38 -08:00
|
|
|
|
#include "base/compiler_specific.h"
|
2014-08-14 09:51:26 -07:00
|
|
|
|
#include "base/logging.h"
|
2016-01-06 12:22:50 -05:00
|
|
|
|
#include "base/macros.h"
|
2015-02-11 13:39:38 -08:00
|
|
|
|
#include "build/build_config.h"
|
2014-08-14 09:51:26 -07:00
|
|
|
|
#include "util/misc/initialization_state.h"
|
|
|
|
|
|
|
|
|
|
namespace crashpad {
|
|
|
|
|
|
2015-08-12 20:47:36 -04:00
|
|
|
|
#if DCHECK_IS_ON() || DOXYGEN
|
2014-08-14 09:51:26 -07:00
|
|
|
|
|
|
|
|
|
//! \brief Tracks whether data are initialized, triggering a DCHECK assertion
|
|
|
|
|
//! on an invalid data access.
|
|
|
|
|
//!
|
|
|
|
|
//! Put an InitializationStateDcheck member into a class to help DCHECK that
|
|
|
|
|
//! it’s in the right states at the right times. This is useful for classes with
|
|
|
|
|
//! Initialize() methods. The chief advantage of InitializationStateDcheck over
|
|
|
|
|
//! having a member variable to track state is that when the only use of the
|
|
|
|
|
//! variable is to DCHECK, it wastes space (in memory and executable code) in
|
doc: Fix all Doxygen warnings, cleaning up some generated documentation
This makes Doxygen’s output more actionable by setting QUIET = YES to
suppress verbose progress spew, and WARN_IF_UNDOCUMENTED = NO to prevent
warnings for undocumented classes and members from being generated. The
latter is too noisy, producing 721 warnings in the current codebase.
The remaining warnings produced by Doxygen were useful and actionable.
They fell into two categories: abuses of Doxygen’s markup syntax, and
missing (or misspelled) parameter documentation. In a small number of
cases, pass-through parameters had intentionally been left undocumented.
In these cases, they are now given blank \param descriptions. This is
not optimal, but there doesn’t appear to be any other way to tell
Doxygen to allow a single parameter to be undocumented.
Some tricky Doxygen errors were resolved by asking it to not enter
directiores that we do not provide documentation in (such as the
“on-platform” compat directories, compat/mac and compat/win, as well as
compat/non_cxx11_lib) while allowing it to enter the
“off-platform” directories that we do document (compat/non_mac and
compat/non_win).
A Doxygen run (doc/support/generate_doxygen.sh) now produces no output
at all. It would produce warnings if any were triggered.
Not directly related, but still relevant to documentation,
doc/support/generate.sh is updated to remove temporary removals of
now-extinct files and directories. doc/appengine/README is updated so
that a consistent path to “goapp” is used throughout the file.
Change-Id: I300730c04de4d3340551ea3086ca70cc5ff862d1
Reviewed-on: https://chromium-review.googlesource.com/408812
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2016-11-08 14:23:09 -05:00
|
|
|
|
//! non-DCHECK builds unless the code is also peppered with ugly `#%ifdef`s.
|
2014-08-14 09:51:26 -07:00
|
|
|
|
//!
|
doc: Fix all Doxygen warnings, cleaning up some generated documentation
This makes Doxygen’s output more actionable by setting QUIET = YES to
suppress verbose progress spew, and WARN_IF_UNDOCUMENTED = NO to prevent
warnings for undocumented classes and members from being generated. The
latter is too noisy, producing 721 warnings in the current codebase.
The remaining warnings produced by Doxygen were useful and actionable.
They fell into two categories: abuses of Doxygen’s markup syntax, and
missing (or misspelled) parameter documentation. In a small number of
cases, pass-through parameters had intentionally been left undocumented.
In these cases, they are now given blank \param descriptions. This is
not optimal, but there doesn’t appear to be any other way to tell
Doxygen to allow a single parameter to be undocumented.
Some tricky Doxygen errors were resolved by asking it to not enter
directiores that we do not provide documentation in (such as the
“on-platform” compat directories, compat/mac and compat/win, as well as
compat/non_cxx11_lib) while allowing it to enter the
“off-platform” directories that we do document (compat/non_mac and
compat/non_win).
A Doxygen run (doc/support/generate_doxygen.sh) now produces no output
at all. It would produce warnings if any were triggered.
Not directly related, but still relevant to documentation,
doc/support/generate.sh is updated to remove temporary removals of
now-extinct files and directories. doc/appengine/README is updated so
that a consistent path to “goapp” is used throughout the file.
Change-Id: I300730c04de4d3340551ea3086ca70cc5ff862d1
Reviewed-on: https://chromium-review.googlesource.com/408812
Reviewed-by: Robert Sesek <rsesek@chromium.org>
2016-11-08 14:23:09 -05:00
|
|
|
|
//! This implementation concentrates the ugly `#%ifdef`s in one location.
|
2014-08-14 09:51:26 -07:00
|
|
|
|
//!
|
|
|
|
|
//! Usage:
|
|
|
|
|
//!
|
|
|
|
|
//! \code
|
|
|
|
|
//! class Class {
|
|
|
|
|
//! public:
|
|
|
|
|
//! Class() : initialized_() {}
|
|
|
|
|
//!
|
|
|
|
|
//! void Initialize() {
|
|
|
|
|
//! INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
|
|
|
|
|
//! // Perform initialization.
|
|
|
|
|
//! INITIALIZATION_STATE_SET_VALID(initialized_);
|
|
|
|
|
//! }
|
|
|
|
|
//!
|
|
|
|
|
//! void DoSomething() {
|
|
|
|
|
//! INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
|
|
|
|
//! // Do something.
|
|
|
|
|
//! }
|
|
|
|
|
//!
|
|
|
|
|
//! private:
|
|
|
|
|
//! InitializationStateDcheck initialized_;
|
|
|
|
|
//! };
|
|
|
|
|
//! \endcode
|
|
|
|
|
class InitializationStateDcheck : public InitializationState {
|
|
|
|
|
public:
|
|
|
|
|
InitializationStateDcheck() : InitializationState() {}
|
|
|
|
|
|
|
|
|
|
//! \brief Returns the object’s state.
|
|
|
|
|
//!
|
|
|
|
|
//! Consumers of this class should not call this method. Use the
|
|
|
|
|
//! INITIALIZATION_STATE_SET_INITIALIZING(), INITIALIZATION_STATE_SET_VALID(),
|
|
|
|
|
//! and INITIALIZATION_STATE_DCHECK_VALID() macros instead.
|
|
|
|
|
//
|
|
|
|
|
// The superclass’ state() accessor is protected, but it needs to be exposed
|
|
|
|
|
// to consumers of this class for the macros below to work properly. The
|
|
|
|
|
// macros prefer access to the unerlying state value over a simple boolean
|
|
|
|
|
// because with access to the state value, DCHECK_EQ can be used, which, when
|
|
|
|
|
// tripped, prints both the expected and observed values. This can aid
|
|
|
|
|
// troubleshooting.
|
|
|
|
|
State state() const { return InitializationState::state(); }
|
|
|
|
|
|
|
|
|
|
//! \brief Marks an uninitialized object as initializing.
|
|
|
|
|
//!
|
|
|
|
|
//! If the object is in the #kStateUninitialized state, changes its state to
|
|
|
|
|
//! #kStateInvalid (initializing) and returns the previous
|
|
|
|
|
//! (#kStateUninitialized) state. Otherwise, returns the object’s current
|
|
|
|
|
//! state.
|
|
|
|
|
//!
|
|
|
|
|
//! Consumers of this class should not call this method. Use the
|
|
|
|
|
//! INITIALIZATION_STATE_SET_INITIALIZING() macro instead.
|
|
|
|
|
State SetInitializing();
|
|
|
|
|
|
|
|
|
|
//! \brief Marks an initializing object as valid.
|
|
|
|
|
//!
|
|
|
|
|
//! If the object is in the #kStateInvalid (initializing) state, changes its
|
|
|
|
|
//! state to #kStateValid and returns the previous (#kStateInvalid) state.
|
|
|
|
|
//! Otherwise, returns the object’s current state.
|
|
|
|
|
//!
|
|
|
|
|
//! Consumers of this class should not call this method. Use the
|
|
|
|
|
//! INITIALIZATION_STATE_SET_VALID() macro instead.
|
|
|
|
|
State SetValid();
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(InitializationStateDcheck);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Using macros enables the non-DCHECK no-op implementation below to be more
|
|
|
|
|
// compact and less intrusive. These are macros instead of methods that call
|
|
|
|
|
// DCHECK to enable the DCHECK failure message to point to the correct file and
|
|
|
|
|
// line number, and to allow additional messages to be streamed on failure with
|
|
|
|
|
// the << operator.
|
|
|
|
|
|
|
|
|
|
//! \brief Checks that a crashpad::InitializationStateDcheck object is in the
|
|
|
|
|
//! crashpad::InitializationState::kStateUninitialized state, and changes
|
|
|
|
|
//! its state to initializing
|
|
|
|
|
//! (crashpad::InitializationState::kStateInvalid).
|
|
|
|
|
//!
|
|
|
|
|
//! If the object is not in the correct state, a DCHECK assertion is triggered
|
|
|
|
|
//! and the object’s state remains unchanged.
|
|
|
|
|
//!
|
|
|
|
|
//! \param[in] initialization_state_dcheck A crashpad::InitializationStateDcheck
|
|
|
|
|
//! object.
|
|
|
|
|
//!
|
|
|
|
|
//! \sa crashpad::InitializationStateDcheck
|
|
|
|
|
#define INITIALIZATION_STATE_SET_INITIALIZING(initialization_state_dcheck) \
|
|
|
|
|
DCHECK_EQ((initialization_state_dcheck).SetInitializing(), \
|
|
|
|
|
(initialization_state_dcheck).kStateUninitialized)
|
|
|
|
|
|
|
|
|
|
//! \brief Checks that a crashpad::InitializationStateDcheck object is in the
|
|
|
|
|
//! initializing (crashpad::InitializationState::kStateInvalid) state, and
|
|
|
|
|
//! changes its state to crashpad::InitializationState::kStateValid.
|
|
|
|
|
//!
|
|
|
|
|
//! If the object is not in the correct state, a DCHECK assertion is triggered
|
|
|
|
|
//! and the object’s state remains unchanged.
|
|
|
|
|
//!
|
|
|
|
|
//! \param[in] initialization_state_dcheck A crashpad::InitializationStateDcheck
|
|
|
|
|
//! object.
|
|
|
|
|
//!
|
|
|
|
|
//! \sa crashpad::InitializationStateDcheck
|
|
|
|
|
#define INITIALIZATION_STATE_SET_VALID(initialization_state_dcheck) \
|
|
|
|
|
DCHECK_EQ((initialization_state_dcheck).SetValid(), \
|
|
|
|
|
(initialization_state_dcheck).kStateInvalid)
|
|
|
|
|
|
|
|
|
|
//! \brief Checks that a crashpad::InitializationStateDcheck object is in the
|
|
|
|
|
//! crashpad::InitializationState::kStateValid state.
|
|
|
|
|
//!
|
|
|
|
|
//! If the object is not in the correct state, a DCHECK assertion is triggered.
|
|
|
|
|
//!
|
|
|
|
|
//! \param[in] initialization_state_dcheck A crashpad::InitializationStateDcheck
|
|
|
|
|
//! object.
|
|
|
|
|
//!
|
|
|
|
|
//! \sa crashpad::InitializationStateDcheck
|
|
|
|
|
#define INITIALIZATION_STATE_DCHECK_VALID(initialization_state_dcheck) \
|
|
|
|
|
DCHECK_EQ((initialization_state_dcheck).state(), \
|
|
|
|
|
(initialization_state_dcheck).kStateValid)
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
2015-02-11 13:39:38 -08:00
|
|
|
|
#if defined(COMPILER_MSVC)
|
|
|
|
|
// bool[0] (below) is not accepted by MSVC.
|
|
|
|
|
struct InitializationStateDcheck {
|
|
|
|
|
};
|
|
|
|
|
#else
|
2014-08-14 09:51:26 -07:00
|
|
|
|
// Since this is to be used as a DCHECK (for debugging), it should be
|
|
|
|
|
// non-intrusive in non-DCHECK (non-debug, release) builds. An empty struct
|
|
|
|
|
// would still have a nonzero size (rationale:
|
|
|
|
|
// http://www.stroustrup.com/bs_faq2.html#sizeof-empty). Zero-length arrays are
|
|
|
|
|
// technically invalid according to the standard, but clang and g++ accept them
|
|
|
|
|
// without complaint even with warnings turned up. They take up no space at all,
|
|
|
|
|
// and they can be “initialized” with the same () syntax used to initialize
|
2015-08-12 20:47:36 -04:00
|
|
|
|
// objects of the DCHECK_IS_ON() InitializationStateDcheck class above.
|
2014-11-05 14:09:01 -05:00
|
|
|
|
using InitializationStateDcheck = bool[0];
|
2015-02-11 13:39:38 -08:00
|
|
|
|
#endif // COMPILER_MSVC
|
2014-08-14 09:51:26 -07:00
|
|
|
|
|
2015-02-11 13:39:38 -08:00
|
|
|
|
// Avoid triggering warnings by repurposing these macros when DCHECKs are
|
|
|
|
|
// disabled.
|
2014-08-14 09:51:26 -07:00
|
|
|
|
#define INITIALIZATION_STATE_SET_INITIALIZING(initialization_state_dcheck) \
|
2015-02-11 13:39:38 -08:00
|
|
|
|
ALLOW_UNUSED_LOCAL(initialization_state_dcheck)
|
2014-08-14 09:51:26 -07:00
|
|
|
|
#define INITIALIZATION_STATE_SET_VALID(initialization_state_dcheck) \
|
2015-02-11 13:39:38 -08:00
|
|
|
|
ALLOW_UNUSED_LOCAL(initialization_state_dcheck)
|
2014-08-14 09:51:26 -07:00
|
|
|
|
#define INITIALIZATION_STATE_DCHECK_VALID(initialization_state_dcheck) \
|
2015-02-11 13:39:38 -08:00
|
|
|
|
ALLOW_UNUSED_LOCAL(initialization_state_dcheck)
|
2014-08-14 09:51:26 -07:00
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
} // namespace crashpad
|
|
|
|
|
|
|
|
|
|
#endif // CRASHPAD_UTIL_MISC_INITIALIZATION_INITIALIZATION_STATE_DCHECK_H_
|