]> git.saurik.com Git - wxWidgets.git/blob - samples/debugrpt/debugrpt.cpp
src/common/wxchar.cpps/wxConvLocal/wxConvLibs/g as otherwise we may fail to convert...
[wxWidgets.git] / samples / debugrpt / debugrpt.cpp
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"
17 #include "wx/log.h"
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 (
41 //_T("http://iml2.hitchcock.org/intranet/crashes/wxtest"),
42 _T("http://your.url.here/"),
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
72 // ----------------------------------------------------------------------------
73 // helper functions
74 // ----------------------------------------------------------------------------
75
76 // just some functions to get a slightly deeper stack trace
77 static void bar(const wxChar *p)
78 {
79 char *pc = 0;
80 *pc = *p;
81
82 printf("bar: %s\n", p);
83 }
84
85 void baz(const wxString& s)
86 {
87 printf("baz: %s\n", s.c_str());
88 }
89
90 void foo(int n)
91 {
92 if ( n % 2 )
93 baz(wxT("odd"));
94 else
95 bar(wxT("even"));
96 }
97
98 // ----------------------------------------------------------------------------
99 // application class
100 // ----------------------------------------------------------------------------
101
102 // this is a usual application class modified to work with debug reporter
103 //
104 // basically just 2 things are necessary: call wxHandleFatalExceptions() as
105 // early as possible and override OnFatalException() to create the report there
106 class MyApp : public wxApp
107 {
108 public:
109 virtual bool OnInit()
110 {
111 wxHandleFatalExceptions();
112
113 if ( !wxApp::OnInit() )
114 return false;
115
116 return true;
117 }
118
119 virtual int OnRun()
120 {
121 // a real program would be presumably be a bit harder to crash than
122 // just pressing "yes" in a dialog... but this is just an example
123 switch ( wxMessageBox
124 (
125 _T("Generate report for crash (or just current context)?"),
126 _T("wxDebugReport Test"),
127 wxYES_NO | wxCANCEL
128 ) )
129 {
130 case wxYES:
131 // this call is going to crash
132 foo(32);
133 foo(17);
134 break;
135
136 case wxNO:
137 // example of manually generated report, this could be also
138 // used in wxApp::OnAssert()
139 GenerateReport(wxDebugReport::Context_Current);
140 break;
141
142 case wxCANCEL:
143 break;
144 }
145
146 return 0;
147 }
148
149 virtual void OnFatalException()
150 {
151 GenerateReport(wxDebugReport::Context_Exception);
152 }
153
154 void GenerateReport(wxDebugReport::Context ctx)
155 {
156 MyDebugReport report;
157
158 // add all standard files: currently this means just a minidump and an
159 // XML file with system info and stack trace
160 report.AddAll(ctx);
161
162 // you can also call report.AddFile(...) with your own log files, files
163 // created using wxRegKey::Export() and so on, here we just add a test
164 // file containing the date of the crash
165 wxFileName fn(report.GetDirectory(), _T("timestamp.my"));
166 wxFFile file(fn.GetFullPath(), _T("w"));
167 if ( file.IsOpened() )
168 {
169 wxDateTime dt = wxDateTime::Now();
170 file.Write(dt.FormatISODate() + _T(' ') + dt.FormatISOTime());
171 file.Close();
172 }
173
174 report.AddFile(fn.GetFullName(), _T("timestamp of this report"));
175
176 // calling Show() is not mandatory, but is more polite
177 if ( wxDebugReportPreviewStd().Show(report) )
178 {
179 if ( report.Process() )
180 {
181 // report successfully uploaded
182 }
183 }
184 //else: user cancelled the report
185 }
186 };
187
188 IMPLEMENT_APP(MyApp)
189