]>
Commit | Line | Data |
---|---|---|
ce4fd7b5 VZ |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: debugrpt.cpp | |
3 | // Purpose: minimal sample showing wxDebugReport and related classes | |
4 | // Author: Vadim Zeitlin | |
5 | // Modified by: | |
6 | // Created: 2005-01-20 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) 2005 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> | |
9 | // License: wxWindows licence | |
10 | /////////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // ---------------------------------------------------------------------------- | |
13 | // headers | |
14 | // ---------------------------------------------------------------------------- | |
15 | ||
16 | #include "wx/app.h" | |
61639efb | 17 | #include "wx/log.h" |
ce4fd7b5 VZ |
18 | #include "wx/datetime.h" |
19 | #include "wx/ffile.h" | |
20 | #include "wx/filename.h" | |
21 | #include "wx/dynlib.h" | |
22 | #include "wx/debugrpt.h" | |
23 | ||
24 | #include "wx/msgdlg.h" | |
25 | ||
26 | #if !wxUSE_DEBUGREPORT | |
27 | #error "This sample can't be built without wxUSE_DEBUGREPORT" | |
28 | #endif // wxUSE_DEBUGREPORT | |
29 | ||
30 | // ---------------------------------------------------------------------------- | |
31 | // custom debug reporting class | |
32 | // ---------------------------------------------------------------------------- | |
33 | ||
34 | // this is your custom debug reporter, you will probably want to parse the XML | |
35 | // document in OnServerReply() instead of just dumping it as I do | |
36 | class MyDebugReport : public wxDebugReportUpload | |
37 | { | |
38 | public: | |
39 | MyDebugReport() : wxDebugReportUpload | |
40 | ( | |
478cde32 | 41 | //_T("http://iml2.hitchcock.org/intranet/crashes/wxtest"), |
985604c1 | 42 | _T("http://your.url.here/"), |
ce4fd7b5 VZ |
43 | _T("report:file"), |
44 | _T("action") | |
45 | ) | |
46 | { | |
47 | } | |
48 | ||
49 | protected: | |
50 | virtual bool OnServerReply(const wxArrayString& reply) | |
51 | { | |
52 | if ( reply.IsEmpty() ) | |
53 | { | |
54 | wxLogError(_T("Didn't receive the expected server reply.")); | |
55 | return false; | |
56 | } | |
57 | ||
58 | wxString s(_T("Server replied:\n")); | |
59 | ||
60 | const size_t count = reply.GetCount(); | |
61 | for ( size_t n = 0; n < count; n++ ) | |
62 | { | |
63 | s << _T('\t') << reply[n] << _T('\n'); | |
64 | } | |
65 | ||
66 | wxLogMessage(_T("%s"), s.c_str()); | |
67 | ||
68 | return true; | |
69 | } | |
70 | }; | |
71 | ||
ed99e548 VZ |
72 | // another possibility would be to build email library from contrib and use |
73 | // this class, after uncommenting it: | |
74 | #if 0 | |
75 | ||
76 | #include "wx/net/email.h" | |
77 | ||
78 | class MyDebugReport : public wxDebugReportCompress | |
79 | { | |
80 | public: | |
81 | virtual bool DoProcess() | |
82 | { | |
83 | if ( !wxDebugReportCompress::DoProcess() ) | |
84 | return false; | |
85 | wxMailMessage msg(GetReportName() + _T(" crash report"), | |
86 | _T("vadim@wxwindows.org"), | |
87 | wxEmptyString, // mail body | |
88 | wxEmptyString, // from address | |
89 | GetCompressedFileName(), | |
90 | _T("crashreport.zip")); | |
91 | ||
92 | return wxEmail::Send(msg); | |
93 | } | |
94 | }; | |
95 | ||
96 | #endif // 0 | |
97 | ||
ce4fd7b5 VZ |
98 | // ---------------------------------------------------------------------------- |
99 | // helper functions | |
100 | // ---------------------------------------------------------------------------- | |
101 | ||
102 | // just some functions to get a slightly deeper stack trace | |
103 | static void bar(const wxChar *p) | |
104 | { | |
105 | char *pc = 0; | |
106 | *pc = *p; | |
107 | ||
108 | printf("bar: %s\n", p); | |
109 | } | |
110 | ||
111 | void baz(const wxString& s) | |
112 | { | |
113 | printf("baz: %s\n", s.c_str()); | |
114 | } | |
115 | ||
116 | void foo(int n) | |
117 | { | |
118 | if ( n % 2 ) | |
119 | baz(wxT("odd")); | |
120 | else | |
121 | bar(wxT("even")); | |
122 | } | |
123 | ||
124 | // ---------------------------------------------------------------------------- | |
125 | // application class | |
126 | // ---------------------------------------------------------------------------- | |
127 | ||
128 | // this is a usual application class modified to work with debug reporter | |
129 | // | |
130 | // basically just 2 things are necessary: call wxHandleFatalExceptions() as | |
131 | // early as possible and override OnFatalException() to create the report there | |
132 | class MyApp : public wxApp | |
133 | { | |
134 | public: | |
135 | virtual bool OnInit() | |
136 | { | |
137 | wxHandleFatalExceptions(); | |
138 | ||
139 | if ( !wxApp::OnInit() ) | |
140 | return false; | |
141 | ||
142 | return true; | |
143 | } | |
144 | ||
145 | virtual int OnRun() | |
146 | { | |
147 | // a real program would be presumably be a bit harder to crash than | |
148 | // just pressing "yes" in a dialog... but this is just an example | |
149 | switch ( wxMessageBox | |
150 | ( | |
151 | _T("Generate report for crash (or just current context)?"), | |
152 | _T("wxDebugReport Test"), | |
153 | wxYES_NO | wxCANCEL | |
154 | ) ) | |
155 | { | |
156 | case wxYES: | |
157 | // this call is going to crash | |
158 | foo(32); | |
159 | foo(17); | |
160 | break; | |
161 | ||
162 | case wxNO: | |
163 | // example of manually generated report, this could be also | |
164 | // used in wxApp::OnAssert() | |
478cde32 | 165 | GenerateReport(wxDebugReport::Context_Current); |
ce4fd7b5 VZ |
166 | break; |
167 | ||
168 | case wxCANCEL: | |
169 | break; | |
170 | } | |
171 | ||
172 | return 0; | |
173 | } | |
174 | ||
175 | virtual void OnFatalException() | |
176 | { | |
177 | GenerateReport(wxDebugReport::Context_Exception); | |
178 | } | |
179 | ||
180 | void GenerateReport(wxDebugReport::Context ctx) | |
181 | { | |
182 | MyDebugReport report; | |
183 | ||
184 | // add all standard files: currently this means just a minidump and an | |
185 | // XML file with system info and stack trace | |
186 | report.AddAll(ctx); | |
187 | ||
188 | // you can also call report.AddFile(...) with your own log files, files | |
189 | // created using wxRegKey::Export() and so on, here we just add a test | |
190 | // file containing the date of the crash | |
191 | wxFileName fn(report.GetDirectory(), _T("timestamp.my")); | |
192 | wxFFile file(fn.GetFullPath(), _T("w")); | |
193 | if ( file.IsOpened() ) | |
194 | { | |
195 | wxDateTime dt = wxDateTime::Now(); | |
196 | file.Write(dt.FormatISODate() + _T(' ') + dt.FormatISOTime()); | |
197 | file.Close(); | |
198 | } | |
199 | ||
200 | report.AddFile(fn.GetFullName(), _T("timestamp of this report")); | |
201 | ||
202 | // calling Show() is not mandatory, but is more polite | |
203 | if ( wxDebugReportPreviewStd().Show(report) ) | |
204 | { | |
205 | if ( report.Process() ) | |
206 | { | |
207 | // report successfully uploaded | |
208 | } | |
209 | } | |
210 | //else: user cancelled the report | |
211 | } | |
212 | }; | |
213 | ||
214 | IMPLEMENT_APP(MyApp) | |
215 |