fune/toolkit/crashreporter/CrashAnnotations.h.in
Gabriele Svelto aa43fa218e Bug 1831092 - Use the new pull-based API for all crash annotations and remove the global annotations table r=jgilbert,necko-reviewers,media-playback-reviewers,profiler-reviewers,win-reviewers,padenot,handyman,afranchuk,valentin,alwu,sotaro
This changes comes with several different refactorings all rolled into one,
unfotunately I couldn't find a way to pull them apart:
- First of all annotations now can either recorded (that is, we copy the value
  and have the crash reporting code own the copy) or registered. Several
  annotations are changed to use this functionality so that we don't need to
  update them as their value change.
- The code in the exception handler is modified to read the annotations from
  the mozannotation_client crate. This has the unfortunate side-effect that
  we need three different bits of code to serialize them: one for annotations
  read from a child process, one for reading annotations from the main process
  outside of the exception handler and one for reading annotations from the
  main process within the exception handler. As we move to fully
  out-of-process crash reporting the last two methods will go away.
- The mozannotation_client crate now doesn't record annotation types anymore.
  I realized as I was working on this that storing types at runtime has two
  issues: the first one is that buggy code might change the type of an
  annotation (that is record it under two different types at two different
  moments), the second issue is that types might become corrupt during a
  crash, so better enforce them at annotation-writing time. The end result is
  that the mozannotation_* crates now only store byte buffers, track the
  format the data is stored in (null-terminated string, fixed size buffer,
  etc...) but not the type of data each annotation is supposed to contain.
- Which brings us to the next change: concrete types for annotations are now
  enforced when they're written out. If an annotation doesn't match the
  expected type it's skipped. Storing an annotation with the wrong type will
  also trigger an assertion in debug builds.

Differential Revision: https://phabricator.services.mozilla.com/D195248
2024-03-04 10:24:43 +00:00

123 lines
3.5 KiB
C

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef CrashAnnotations_h
#define CrashAnnotations_h
#include <cstddef>
#include <cstdint>
namespace CrashReporter {
// Typed enum representing all crash annotations
enum class Annotation : uint32_t {
${enum}
};
// Stringified crash annotation names
const char* const kAnnotationStrings[] = {
${strings}
};
// Type of each annotation
enum class AnnotationType : uint8_t {
String = 0, // Any type of string, const char*, nsCString, etc...
Boolean = 1, // Stored as a byte
U32 = 2, // C/C++'s uint32_t or Rust's u32
U64 = 3, // C/C++'s uint64_t or Rust's u64
USize = 4, // C/C++'s size_t or Rust's usize
};
// Type of each annotation
const AnnotationType kAnnotationTypes[] = {
${types}
};
// Allowlist of crash annotations that can be included in a crash ping
const Annotation kCrashPingAllowedList[] = {
${allowedlist}
};
// Annotations which should be skipped when they have specific values
struct AnnotationSkipValue {
Annotation annotation;
const char* value;
};
const AnnotationSkipValue kSkipIfList[] = {
${skiplist}
};
/**
* Return the type of a crash annotation.
*
* @param aAnnotation a crash annotation
* @returns The type of this annotation
*/
static inline AnnotationType TypeOfAnnotation(Annotation aAnnotation) {
return kAnnotationTypes[static_cast<uint32_t>(aAnnotation)];
}
/**
* Return the string representation of a crash annotation.
*
* @param aAnnotation a crash annotation
* @returns A constant string holding the annotation name
*/
static inline const char* AnnotationToString(Annotation aAnnotation) {
return kAnnotationStrings[static_cast<uint32_t>(aAnnotation)];
}
/**
* Converts a string to its corresponding crash annotation.
*
* @param aResult a reference where the annotation will be stored
* @param aValue the string to be converted
* @return true if the string was successfully converted, false if it did not
* correspond to any known annotation
*/
bool AnnotationFromString(Annotation& aResult, const char* aValue);
/**
* Checks if the given crash annotation is allowed for inclusion in the crash
* ping.
*
* @param aAnnotation the crash annotation to be checked
* @return true if the annotation can be included in the crash ping, false
* otherwise
*/
bool IsAnnotationAllowedForPing(Annotation aAnnotation);
/**
* Checks if the annotation should be included. Some annotations are skipped if
* their value matches a specific one (like the value 0).
*
* @param aAnnotation the crash annotation to be checked
* @param aValue the contents of the annotation as a string
* @return true if the annotation should be included, false otherwise
*/
bool ShouldIncludeAnnotation(Annotation aAnnotation, const char* aValue);
/**
* Abstract annotation writer, this is needed only for code that writes out
* annotations in the exception handler.
*/
class AnnotationWriter {
public:
virtual void Write(Annotation aAnnotation, const char* aValue,
size_t aLen = 0) = 0;
virtual void Write(Annotation aAnnotation, bool aValue) = 0;
virtual void Write(Annotation aAnnotation, uint64_t aValue) = 0;
};
#ifdef XP_WIN
extern void RecordDllAnnotations(bool* aBlocklistInitFailed,
bool* aUser32BeforeBlocklist);
#endif // XP_WIN
} // namespace CrashReporter
#endif // CrashAnnotations_h