]> git.saurik.com Git - wxWidgets.git/blame - samples/debugrpt/debugrpt.cpp
silently ignore NULL pointers in MSWOnMeasureItem(): apparently this can happen with...
[wxWidgets.git] / samples / debugrpt / debugrpt.cpp
CommitLineData
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
36class MyDebugReport : public wxDebugReportUpload
37{
38public:
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
49protected:
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
78class MyDebugReport : public wxDebugReportCompress
79{
80public:
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
103static void bar(const wxChar *p)
104{
105 char *pc = 0;
106 *pc = *p;
107
108 printf("bar: %s\n", p);
109}
110
111void baz(const wxString& s)
112{
113 printf("baz: %s\n", s.c_str());
114}
115
116void 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
132class MyApp : public wxApp
133{
134public:
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
214IMPLEMENT_APP(MyApp)
215