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