|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set sw=4 ts=8 et tw=80 : |
|
3 * This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 #include "CrashReporterParent.h" |
|
7 #include "mozilla/dom/ContentParent.h" |
|
8 #include "nsXULAppAPI.h" |
|
9 #include <time.h> |
|
10 |
|
11 #ifdef MOZ_CRASHREPORTER |
|
12 #include "nsExceptionHandler.h" |
|
13 #endif |
|
14 |
|
15 using namespace base; |
|
16 |
|
17 namespace mozilla { |
|
18 namespace dom { |
|
19 |
|
20 void |
|
21 CrashReporterParent::AnnotateCrashReport(const nsCString& key, |
|
22 const nsCString& data) |
|
23 { |
|
24 #ifdef MOZ_CRASHREPORTER |
|
25 mNotes.Put(key, data); |
|
26 #endif |
|
27 } |
|
28 |
|
29 bool |
|
30 CrashReporterParent::RecvAppendAppNotes(const nsCString& data) |
|
31 { |
|
32 mAppNotes.Append(data); |
|
33 return true; |
|
34 } |
|
35 |
|
36 mozilla::ipc::IProtocol* |
|
37 CrashReporterParent::CloneProtocol(Channel* aChannel, |
|
38 mozilla::ipc::ProtocolCloneContext* aCtx) |
|
39 { |
|
40 #ifdef MOZ_CRASHREPORTER |
|
41 ContentParent* contentParent = aCtx->GetContentParent(); |
|
42 CrashReporter::ThreadId childThreadId = contentParent->Pid(); |
|
43 GeckoProcessType childProcessType = |
|
44 contentParent->Process()->GetProcessType(); |
|
45 |
|
46 nsAutoPtr<PCrashReporterParent> actor( |
|
47 contentParent->AllocPCrashReporterParent(childThreadId, |
|
48 childProcessType) |
|
49 ); |
|
50 if (!actor || |
|
51 !contentParent->RecvPCrashReporterConstructor(actor, |
|
52 childThreadId, |
|
53 childThreadId)) { |
|
54 return nullptr; |
|
55 } |
|
56 |
|
57 return actor.forget(); |
|
58 #else |
|
59 MOZ_CRASH("Not Implemented"); |
|
60 return nullptr; |
|
61 #endif |
|
62 } |
|
63 |
|
64 CrashReporterParent::CrashReporterParent() |
|
65 : |
|
66 #ifdef MOZ_CRASHREPORTER |
|
67 mNotes(4), |
|
68 #endif |
|
69 mStartTime(::time(nullptr)) |
|
70 , mInitialized(false) |
|
71 { |
|
72 MOZ_COUNT_CTOR(CrashReporterParent); |
|
73 } |
|
74 |
|
75 CrashReporterParent::~CrashReporterParent() |
|
76 { |
|
77 MOZ_COUNT_DTOR(CrashReporterParent); |
|
78 } |
|
79 |
|
80 void |
|
81 CrashReporterParent::SetChildData(const NativeThreadId& tid, |
|
82 const uint32_t& processType) |
|
83 { |
|
84 mInitialized = true; |
|
85 mMainThread = tid; |
|
86 mProcessType = processType; |
|
87 } |
|
88 |
|
89 #ifdef MOZ_CRASHREPORTER |
|
90 bool |
|
91 CrashReporterParent::GenerateCrashReportForMinidump(nsIFile* minidump, |
|
92 const AnnotationTable* processNotes) |
|
93 { |
|
94 if (!CrashReporter::GetIDFromMinidump(minidump, mChildDumpID)) |
|
95 return false; |
|
96 return GenerateChildData(processNotes); |
|
97 } |
|
98 |
|
99 bool |
|
100 CrashReporterParent::GenerateChildData(const AnnotationTable* processNotes) |
|
101 { |
|
102 MOZ_ASSERT(mInitialized); |
|
103 |
|
104 nsAutoCString type; |
|
105 switch (mProcessType) { |
|
106 case GeckoProcessType_Content: |
|
107 type = NS_LITERAL_CSTRING("content"); |
|
108 break; |
|
109 case GeckoProcessType_Plugin: |
|
110 type = NS_LITERAL_CSTRING("plugin"); |
|
111 break; |
|
112 default: |
|
113 NS_ERROR("unknown process type"); |
|
114 break; |
|
115 } |
|
116 mNotes.Put(NS_LITERAL_CSTRING("ProcessType"), type); |
|
117 |
|
118 char startTime[32]; |
|
119 sprintf(startTime, "%lld", static_cast<long long>(mStartTime)); |
|
120 mNotes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime)); |
|
121 |
|
122 if (!mAppNotes.IsEmpty()) |
|
123 mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes); |
|
124 |
|
125 bool ret = CrashReporter::AppendExtraData(mChildDumpID, mNotes); |
|
126 if (ret && processNotes) |
|
127 ret = CrashReporter::AppendExtraData(mChildDumpID, *processNotes); |
|
128 if (!ret) |
|
129 NS_WARNING("problem appending child data to .extra"); |
|
130 return ret; |
|
131 } |
|
132 #endif |
|
133 |
|
134 } // namespace dom |
|
135 } // namespace mozilla |