2016-10-12 00:25:17 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* 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/. */
|
|
|
|
|
|
|
|
#include "CrashReporterMetadataShmem.h"
|
|
|
|
#include "mozilla/Attributes.h"
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
#include "mozilla/EnumeratedRange.h"
|
2016-10-12 00:25:17 +03:00
|
|
|
#include "nsISupportsImpl.h"
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace ipc {
|
|
|
|
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
using CrashReporter::Annotation;
|
|
|
|
|
2016-10-12 00:25:17 +03:00
|
|
|
enum class EntryType : uint8_t {
|
|
|
|
None,
|
|
|
|
Annotation,
|
|
|
|
};
|
|
|
|
|
|
|
|
CrashReporterMetadataShmem::CrashReporterMetadataShmem(const Shmem& aShmem)
|
|
|
|
: mShmem(aShmem) {
|
|
|
|
MOZ_COUNT_CTOR(CrashReporterMetadataShmem);
|
|
|
|
}
|
|
|
|
|
|
|
|
CrashReporterMetadataShmem::~CrashReporterMetadataShmem() {
|
|
|
|
MOZ_COUNT_DTOR(CrashReporterMetadataShmem);
|
|
|
|
}
|
|
|
|
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
void CrashReporterMetadataShmem::AnnotateCrashReport(Annotation aKey,
|
|
|
|
const nsCString& aData) {
|
|
|
|
mAnnotations[aKey] = aData;
|
2016-10-12 00:25:17 +03:00
|
|
|
SyncNotesToShmem();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CrashReporterMetadataShmem::AppendAppNotes(const nsCString& aData) {
|
|
|
|
mAppNotes.Append(aData);
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
mAnnotations[Annotation::Notes] = mAppNotes;
|
2016-10-12 00:25:17 +03:00
|
|
|
SyncNotesToShmem();
|
|
|
|
}
|
|
|
|
|
|
|
|
class MOZ_STACK_CLASS MetadataShmemWriter {
|
|
|
|
public:
|
|
|
|
explicit MetadataShmemWriter(const Shmem& aShmem)
|
|
|
|
: mCursor(aShmem.get<uint8_t>()), mEnd(mCursor + aShmem.Size<uint8_t>()) {
|
|
|
|
*mCursor = uint8_t(EntryType::None);
|
|
|
|
}
|
|
|
|
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
MOZ_MUST_USE bool WriteAnnotation(Annotation aKey, const nsCString& aValue) {
|
2016-10-12 00:25:17 +03:00
|
|
|
// This shouldn't happen because Commit() guarantees mCursor < mEnd. But
|
|
|
|
// we might as well be safe.
|
|
|
|
if (mCursor >= mEnd) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save the current position so we can write the entry type if the entire
|
|
|
|
// entry fits.
|
|
|
|
uint8_t* start = mCursor++;
|
|
|
|
if (!Write(aKey) || !Write(aValue)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return Commit(start, EntryType::Annotation);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
// On success, append a new terminal byte. On failure, rollback the cursor.
|
|
|
|
MOZ_MUST_USE bool Commit(uint8_t* aStart, EntryType aType) {
|
|
|
|
MOZ_ASSERT(aStart < mEnd);
|
|
|
|
MOZ_ASSERT(EntryType(*aStart) == EntryType::None);
|
|
|
|
|
|
|
|
if (mCursor >= mEnd) {
|
|
|
|
// No room for a terminating byte - rollback.
|
|
|
|
mCursor = aStart;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Commit the entry and write a new terminal byte.
|
|
|
|
*aStart = uint8_t(aType);
|
|
|
|
*mCursor = uint8_t(EntryType::None);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_MUST_USE bool Write(const nsCString& aString) {
|
|
|
|
// 32-bit length is okay since our shmems are very small (16K),
|
|
|
|
// a huge write would fail anyway.
|
|
|
|
return Write(static_cast<uint32_t>(aString.Length())) &&
|
|
|
|
Write(aString.get(), aString.Length());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
MOZ_MUST_USE bool Write(const T& aT) {
|
|
|
|
return Write(&aT, sizeof(T));
|
|
|
|
}
|
|
|
|
|
|
|
|
MOZ_MUST_USE bool Write(const void* aData, size_t aLength) {
|
|
|
|
if (size_t(mEnd - mCursor) < aLength) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
memcpy(mCursor, aData, aLength);
|
|
|
|
mCursor += aLength;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
// The cursor (beginning at start) always points to a single byte
|
|
|
|
// representing the next EntryType. An EntryType is either None,
|
|
|
|
// indicating there are no more entries, or Annotation, meaning
|
|
|
|
// two strings follow.
|
|
|
|
//
|
|
|
|
// Strings are written as a 32-bit length and byte sequence. After each new
|
|
|
|
// entry, a None entry is always appended, and a subsequent entry will
|
|
|
|
// overwrite this byte.
|
|
|
|
uint8_t* mCursor;
|
|
|
|
uint8_t* mEnd;
|
|
|
|
};
|
|
|
|
|
|
|
|
void CrashReporterMetadataShmem::SyncNotesToShmem() {
|
|
|
|
MetadataShmemWriter writer(mShmem);
|
|
|
|
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
for (auto key : MakeEnumeratedRange(Annotation::Count)) {
|
|
|
|
if (!mAnnotations[key].IsEmpty()) {
|
|
|
|
if (!writer.WriteAnnotation(key, mAnnotations[key])) {
|
|
|
|
return;
|
|
|
|
}
|
2016-10-12 00:25:17 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Helper class to iterate over metadata entries encoded in shmem.
|
|
|
|
class MOZ_STACK_CLASS MetadataShmemReader {
|
|
|
|
public:
|
|
|
|
explicit MetadataShmemReader(const Shmem& aShmem)
|
|
|
|
: mEntryType(EntryType::None) {
|
|
|
|
mCursor = aShmem.get<uint8_t>();
|
|
|
|
mEnd = mCursor + aShmem.Size<uint8_t>();
|
|
|
|
|
|
|
|
// Advance to the first item, if any.
|
|
|
|
Next();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Done() const { return mCursor >= mEnd || Type() == EntryType::None; }
|
|
|
|
EntryType Type() const { return mEntryType; }
|
|
|
|
void Next() {
|
|
|
|
if (mCursor < mEnd) {
|
|
|
|
mEntryType = EntryType(*mCursor++);
|
|
|
|
} else {
|
|
|
|
mEntryType = EntryType::None;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
template <typename T>
|
|
|
|
bool Read(T* aOut) {
|
|
|
|
return Read(aOut, sizeof(T));
|
|
|
|
}
|
|
|
|
|
2016-10-12 00:25:17 +03:00
|
|
|
bool Read(nsCString& aOut) {
|
|
|
|
uint32_t length = 0;
|
|
|
|
if (!Read(&length)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const uint8_t* src = Read(length);
|
|
|
|
if (!src) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
aOut.Assign((const char*)src, length);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool Read(void* aOut, size_t aLength) {
|
|
|
|
const uint8_t* src = Read(aLength);
|
|
|
|
if (!src) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
memcpy(aOut, src, aLength);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If buffer has |aLength| bytes, return cursor and then advance it.
|
|
|
|
// Otherwise, return null.
|
|
|
|
const uint8_t* Read(size_t aLength) {
|
|
|
|
if (size_t(mEnd - mCursor) < aLength) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
const uint8_t* result = mCursor;
|
|
|
|
mCursor += aLength;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const uint8_t* mCursor;
|
|
|
|
const uint8_t* mEnd;
|
|
|
|
EntryType mEntryType;
|
|
|
|
};
|
|
|
|
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
void CrashReporterMetadataShmem::ReadAppNotes(const Shmem& aShmem,
|
|
|
|
AnnotationTable& aNotes) {
|
2016-10-12 00:25:17 +03:00
|
|
|
for (MetadataShmemReader reader(aShmem); !reader.Done(); reader.Next()) {
|
|
|
|
switch (reader.Type()) {
|
|
|
|
case EntryType::Annotation: {
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
Annotation key;
|
|
|
|
nsCString value;
|
|
|
|
if (!reader.Read(&key) || !reader.Read(value)) {
|
2016-10-12 00:25:17 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML
file. The relevant C++ functions are updated to take a typed enum. JavaScript
calls are unaffected but they will throw if the string argument does not
correspond to one of the known entries in the C++ enum. The existing whitelists
and blacklists of annotations are also generated from the YAML file and all
duplicate code related to them has been consolidated. Once written out to the
.extra file the annotations are converted in string form and are no different
than the existing ones.
All existing annotations have been included in the list (and some obsolete ones
have been removed) and all call sites have been updated including tests where
appropriate.
--HG--
extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
2018-07-05 16:42:11 +03:00
|
|
|
aNotes[key] = value;
|
2016-10-12 00:25:17 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
NS_ASSERTION(false, "Unknown metadata entry type");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace ipc
|
|
|
|
} // namespace mozilla
|