Ensure that an out-of-process COM object is started only once.
[wine/wine-kai.git] / tools / bug_report.pl
blob522f36f3d1dc3b9c1a7c6eecc79ff59c1fc0c2db
1 #!/usr/bin/perl
2 ##Wine Quick Debug Report Maker Thingy (WQDRMK)
3 ## Copyright (c) 1998-1999 Adam Sacarny
4 ##Do not say this is yours without my express permisson, or I will
5 ##hunt you down and kill you like the savage animal I am.
6 ##
7 ## Improvements by Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
8 ## (c) 2000
9 ##
10 ## This library is free software; you can redistribute it and/or
11 ## modify it under the terms of the GNU Lesser General Public
12 ## License as published by the Free Software Foundation; either
13 ## version 2.1 of the License, or (at your option) any later version.
15 ## This library is distributed in the hope that it will be useful,
16 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ## Lesser General Public License for more details.
20 ## You should have received a copy of the GNU Lesser General Public
21 ## License along with this library; if not, write to the Free Software
22 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 ##Changelog:
25 ##August 29, 1999 - Work around for debugger exit (or lack thereof)
26 ## - Should now put debugging output in correct place
27 ##April 19, 1999 - Much nicer way to select wine's location
28 ## - Option to disable creation of a debugging output
29 ## - Now places debugging output where it was started
30 ##April 4, 1999 - Sanity check for file locations/wine strippedness
31 ## - Various code cleanups/fixes
32 ##March 21, 1999 - Bash 2.0 STDERR workaround (Thanks Ryan Cumming!)
33 ##March 1, 1999 - Check for stripped build
34 ##February 3, 1999 - Fix to chdir to the program's directory
35 ##February 1, 1999 - Cleaned up code
36 ##January 26, 1999 - Fixed various bugs...
37 ## - Made newbie mode easier
38 ##January 25, 1999 - Initial Release
39 ## -------------------------------------------
40 ##| IRCNET/UNDERNET: jazzfan AOL: Jazzrock12 |
41 ##| E-MAIL: magicbox@bestweb.net ICQ: 19617831|
42 ##| Utah Jazz Page @ http://www.gojazz.net |
43 ##| Wine Builds @ http://www.gojazz.net/wine |
44 ## -------------------------------------------
45 sub do_var {
46 $var=$_[0];
47 $var =~ s/\t//g;
48 return $var;
50 open STDERR, ">&SAVEERR"; open STDERR, ">&STDOUT";
51 $ENV{'SHELL'}="/bin/bash";
52 $var0 = qq{
53 What is your level of WINE expertise? 1-newbie 2-intermediate 3-advanced
55 1 - Makes a debug report as defined in the WINE documentation. Best
56 for new WINE users. If you're not sure what -debugmsg is, then
57 use this mode.
58 2 - Makes a debug report that is more customizable (Example: you can
59 choose what -debugmsg 's to use). You are asked more questions in
60 this mode. May intimidate newbies.
61 3 - Just like 2, but not corner cutting. Assumes you know what you're
62 doing so it leaves out the long descriptions.
64 print do_var($var0)."\n";
65 until ($debuglevel >= 1 and $debuglevel <= 3) {
66 print "Enter your level of WINE expertise (1-3): ";
67 $debuglevel=<STDIN>;
68 chomp $debuglevel;
71 if ($debuglevel < 3) {
72 $var1 = qq{
73 This program will make a debug report for WINE developers. It generates
74 two files. The first one has everything asked for by the bugreports guide;
75 the second has *all* of the debug output, which can go to thousands of
76 lines.
77 To (hopefully) get the bug fixed, report it to the project
78 bug tracking system at http://bugs.winehq.com.
79 Attach the first file to the bug description.
80 Also include detailed description of the problem. The developers
81 might ask you for "the last X lines from the report". If so, just
82 provide the output of the following command:
83 gzip -d (output file) | tail -n (X) > outfile
84 If you do not want to create one of the files, just specify "no file".
86 print do_var($var1);
87 } elsif ($debuglevel =~ 3) {
88 $var2 = qq{
89 This program will output to two files:
90 1. Formatted debug report you might want to post to the newsgroup
91 2. File with ALL the debug output (It will later be compressed with
92 gzip, so leave off the trailing .gz)
93 If you do not want to create one of the files, just type in "no file"
94 and I'll skip it.
96 print do_var($var2);
99 print "\nFilename for the formatted debug report: ";
100 $outfile=<STDIN>;
101 chomp $outfile;
102 $var23 = qq{
103 I don't think you typed in the right filename. Let's try again.
105 while ($outfile =~ /^(\s)*$/) {
106 print do_var($var23);
107 $outfile=<STDIN>;
108 chomp $outfile;
111 print "Filename for full debug output: ";
112 $dbgoutfile=<STDIN>;
113 chomp $dbgoutfile;
114 while ($dbgoutfile =~ /^(\s)*$/) {
115 print do_var($var23);
116 $dbgoutfile=<STDIN>;
117 chomp $dbgoutfile;
120 $var31 = qq{
121 Since you will only be creating the formatted report, I will need a
122 temporary place to put the full output.
123 You may not enter "no file" for this.
124 Enter the filename for the temporary file:
126 if ($outfile ne "no file" and $dbgoutfile eq "no file") {
127 print do_var($var31);
128 $tmpoutfile=<STDIN>;
129 chomp $tmpoutfile;
130 while (($tmpoutfile =~ /^(\s)*$/) or ($tmpoutfile eq "no file")) {
131 print do_var($var23);
132 $tmpoutfile=<STDIN>;
133 chomp $tmpoutfile;
137 $whereis=`whereis wine`;
138 chomp $whereis;
139 print "\nWhere is your copy of Wine located?\n\n";
140 $whereis =~ s/^wine\: //;
141 @locations = split(/\s/,$whereis);
142 print "1 - Unlisted (I'll prompt you for a new location\n";
143 print "2 - Unsure (I'll use #3, that's probably it)\n";
144 $i=2;
145 foreach $location (@locations) {
146 $i++;
147 print "$i - $location\n";
149 print "\n";
150 sub select_wineloc {
153 print "Enter the number that corresponds to Wine's location: ";
154 $wineloc=<STDIN>;
155 chomp $wineloc;
157 while ( ! ( $wineloc >=1 and $wineloc <= 2+@locations ) );
158 if ($wineloc == 1) {
159 $var25 = qq{
160 Enter the full path to wine (Example: /usr/bin/wine):
162 $var26 = qq{
163 Please enter the full path to wine. A full path is the
164 directories leading up to a program's location, and then the
165 program. For example, if you had the program "wine" in the
166 directory "/usr/bin", you would type in "/usr/bin/wine". Now
167 try:
169 print do_var($var25) if $debuglevel == 3;
170 print do_var($var26) if $debuglevel < 3;
171 $wineloc=<STDIN>;
172 chomp $wineloc;
173 while ($wineloc =~ /^(\s)*$/) {
174 print do_var($var23);
175 $wineloc=<STDIN>;
176 chomp $wineloc;
179 elsif ($wineloc == 2) {
180 $wineloc=$locations[0];
182 else {
183 $wineloc=$locations[$wineloc-3];
186 &select_wineloc;
187 print "Checking if $wineloc is stripped...\n";
188 $ifstrip = `nm $wineloc 2>&1`;
189 while ($ifstrip =~ /no symbols/) {
190 $var24 = qq{
191 Your wine is stripped! You probably downloaded it off of the internet.
192 If you have another location of wine that may be used, enter it now.
193 Otherwise, hit control-c and download an unstripped version, then re-run
194 this script. Note: stripped versions make useless debug reports
196 print do_var($var24);
197 &select_wineloc;
198 $ifstrip = `nm $wineloc 2>&1`;
200 while ($ifstrip =~ /not recognized/) {
201 $var26 = qq{
202 Looks like you gave me something that isn't a wine binary (It could be a
203 text file). Try again.
205 print do_var($var26);
206 &select_wineloc;
207 print "Checking if $wineloc is stripped...\n";
208 $ifstrip = `nm $wineloc 2>&1`;
211 print "\nWhat version of windows are you using with wine?\n\n".
212 "0 - None\n".
213 "1 - Windows 3.x\n".
214 "2 - Windows 95\n".
215 "3 - Windows 98\n".
216 "4 - Windows NT 3.5x\n".
217 "5 - Windows NT4.x\n".
218 "6 - Windows 2000\n".
219 "7 - Other\n\n";
222 print "Enter the number that corresponds to your windows version: ";
223 $winver=<STDIN>;
224 chomp $winver;
226 until ($winver >= 0 and $winver <= 7);
227 if ($winver =~ 0) {
228 $winver="None Installed";
229 } elsif ($winver =~ 1) {
230 $winver="Windows 3.x";
231 } elsif ($winver =~ 2) {
232 $winver="Windows 95";
233 } elsif ($winver =~ 3) {
234 $winver="Windows 98";
235 } elsif ($winver =~ 4) {
236 $winver="Windows NT 3.5x";
237 } elsif ($winver =~ 5) {
238 $winver="Windows NT 4.x";
239 } elsif ($winver =~ 6) {
240 $winver="Windows NT 5.x";
241 } elsif ($winver =~ 7) {
242 print "What version of Windows are you using? ";
243 $winver=<STDIN>;
244 chomp $winver;
246 if ($debuglevel < 3) {
247 $var7 = qq{
248 Enter the full path to the program you want to run. Remember what you
249 were told before - a full path is the directories leading up to the
250 program and then the program's name, like /dos/windows/sol.exe, not
251 sol.exe:
253 print do_var($var7);
255 if ($debuglevel =~ 3) {
256 $var8 = qq{
257 Enter the full path to the program you want to run (Example:
258 /dos/windows/sol.exe, NOT sol.exe):
260 print do_var($var8);
262 $program=<STDIN>;
263 chomp $program;
264 while ($program =~ /^(\s)*$/) {
265 print do_var($var23);
266 $program=<STDIN>;
267 chomp $program;
269 $program =~ s/\"//g;
270 $var9 = qq{
271 Enter the name, version, and manufacturer of the program (Example:
272 Netscape Navigator 4.5):
274 print do_var($var9);
275 $progname=<STDIN>;
276 chomp $progname;
277 $var10 = qq{
278 Enter 0 if your program is 16 bit (Windows 3.x), 1 if your program is 32
279 bit (Windows 9x, NT3.x and up), or 2 if you are unsure:
281 print do_var($var10);
282 $progbits=<STDIN>;
283 chomp $progbits;
284 until ($progbits == 0 or $progbits == 1 or $progbits == 2) {
285 print "You must enter 0, 1 or 2!\n";
286 $progbits=<STDIN>;
287 chomp $progbits
289 if ($progbits =~ 0) {
290 $progbits=Win16
291 } elsif ($progbits =~ 1) {
292 $progbits=Win32
293 } else {
294 $progbits = "Unsure"
296 if ($debuglevel > 1) {
297 if ($debuglevel =~ 2) {
298 $var11 = qq{
299 Enter any extra debug options. Default is +relay - If you don't
300 know what options to use, just hit enter, and I'll use those (Example, the
301 developer tells you to re-run with -debugmsg +dosfs,+module you would type
302 in +dosfs,+module). Hit enter if you're not sure what to do:
304 print do_var($var11);
305 } elsif ($debuglevel =~ 3) {
306 $var12 = qq{
307 Enter any debug options you would like to use. Just enter parts after
308 -debugmsg. Default is +relay:
310 print do_var($var12);
312 $debugopts=<STDIN>;
313 chomp $debugopts;
314 if ($debugopts =~ /-debugmsg /) {
315 ($crap, $debugopts) = split / /,$debugopts;
317 if ($debugopts =~ /^\s*$/) {
318 $debugopts="+relay";
320 } elsif ($debuglevel =~ 1) {
321 $debugopts = "+relay";
323 if ($debuglevel > 1) {
324 if ($debuglevel =~ 2) {
325 $var13 = qq{
326 How many trailing lines of debugging info do you want to include in the report
327 you're going to submit (First file)? If a developer asks you to include
328 the last 1000 lines, enter 1000 here. Default is 200, which is reached by
329 pressing enter. (If you're not sure, just hit enter):
331 print do_var($var13);
332 } elsif ($debuglevel =~ 3) {
333 $var14 = qq{
334 Enter how many lines of trailing debugging output you want in your nice
335 formatted report. Default is 200:
337 print do_var($var14);
339 $lastnlines=<STDIN>;
340 chomp $lastnlines;
341 if ($lastnlines =~ /^\s*$/) {
342 $lastnlines=200;
344 } elsif ($debuglevel =~ 1) {
345 $lastnlines=200;
347 if ($debuglevel > 1) {
348 $var15 = qq{
349 Enter any extra options you want to pass to WINE. Strongly recommended you
350 include -managed:
352 print do_var($var15);
353 $extraops=<STDIN>;
354 chomp $extraops;
355 } elsif ($debuglevel =~ 1) {
356 $extraops="-managed";
359 print "\nEnter the name of your distribution (Example: Redhat 6.1): ";
360 $dist=<STDIN>;
361 chomp $dist;
363 if ($debuglevel > 1) {
364 if ($debuglevel =~ 2) {
365 $var16 = qq{
366 When you ran ./configure to build wine, were there any special options
367 you used to do so (Example: --enable-dll)? If you didn't use any special
368 options or didn't compile WINE on your own, just hit enter:
370 print do_var($var16);
371 } elsif ($debuglevel =~ 3) {
372 $var17 = qq{
373 Enter any special options you used when running ./configure for WINE
374 (Default is none, use if you didn't compile wine yourself):
376 print do_var($var17);
378 $configopts=<STDIN>;
379 chomp $configopts;
380 if ($configopts =~ /^\s*$/) {
381 $configopts="None";
383 } elsif ($debuglevel =~ 1) {
384 $configopts="None";
386 if ($debuglevel > 1) {
387 if ($debuglevel =~ 2) {
388 $var18 = qq{
389 Is your wine version CVS or from a .tar.gz file? As in... did you download it
390 off a website/ftpsite or did you/have you run cvs on it to update it?
391 For CVS: YYMMDD, where YY is the year (99), MM is the month (01), and DD
392 is the day (14), that you last updated it (Example: 990114).
393 For tar.gz: Just hit enter and I'll figure out the version for you:
395 print do_var($var18);
396 } elsif ($debuglevel =~ 3) {
397 $var19 = qq{
398 Is your wine from CVS? Enter the last CVS update date for it here, in
399 YYMMDD form (If it's from a tarball, just hit enter):
401 print do_var($var19);
403 $winever=<STDIN>;
404 chomp $winever;
405 if ($winever =~ /[0-9]+/) {
406 $winever .= " CVS";
408 else {
409 $winever = `$wineloc -v 2>&1`;
410 chomp $winever;
412 } elsif ($debuglevel =~ 1) {
413 $winever=`$wineloc -v 2>&1`;
414 chomp $winever;
416 $gccver=`gcc -v 2>&1`;
417 ($leftover,$gccver) = split /\n/,$gccver;
418 chomp $gccver;
419 $cpu=`uname -m`;
420 chomp $cpu;
421 $kernelver=`uname -r`;
422 chomp $kernelver;
423 $ostype=`uname -s`;
424 chomp $ostype;
425 $wineneeds=`ldd $wineloc`;
426 if ($debuglevel < 3) {
427 $var20 = qq{
428 OK, now I'm going to run WINE. I will close it for you once the wine
429 debugger comes up. NOTE: You won't see ANY debug messages. Don't
430 worry, they are being output to a file. Since there are so many, it's
431 not a good idea to have them all output to a terminal (Speed slowdown
432 mainly).
433 WINE will still run much slower than normal, because there will be so
434 many debug messages being output to file.
436 print do_var($var20);
437 } elsif ($debuglevel =~ 3) {
438 $var21 = qq{
439 OK, now it's time to run WINE. I will close down WINE for you after
440 the debugger is finished doing its thing.
442 print do_var($var21);
444 $bashver=qw("/bin/bash -version");
445 if ($bashver =~ /2\./) { $outflags = "2>" }
446 else { $outflags = ">\&" }
447 print "Hit enter to start wine!\n";
448 $blank=<STDIN>;
449 $dir=$program;
450 $dir=~m#(.*)/#;
451 $dir=$1;
452 use Cwd;
453 $nowdir=getcwd;
454 chdir($dir);
455 if (!($outfile =~ /\//) and $outfile ne "no file") {
456 $outfile = "$nowdir/$outfile";
458 if (!($dbgoutfile =~ /\//) and $dbgoutfile ne "no file") {
459 $dbgoutfile = "$nowdir/$dbgoutfile";
461 if (!($tmpoutfile =~ /\//)) {
462 $tmpoutfile = "$nowdir/$tmpoutfile";
464 $SIG{CHLD}=$SIG{CLD}=sub { wait };
465 if ($dbgoutfile ne "no file") {
466 unlink("$dbgoutfile");
467 if ($pid=fork()) {
469 elsif (defined $pid) {
470 close(0);close(1);close(2);
471 exec "echo quit | $wineloc -debugmsg $debugopts $extraops \"$program\" > $dbgoutfile 2>&1";
473 else {
474 die "couldn't fork";
476 while (kill(0, $pid)) {
477 sleep(5);
478 $last = `tail -n 5 $dbgoutfile | grep Wine-dbg`;
479 if ($last =~ /Wine-dbg/) {
480 kill "TERM", $pid;
481 break;
484 if ($outfile ne "no file") {
485 $lastlines=`tail -n $lastnlines $dbgoutfile`;
486 system("gzip $dbgoutfile");
487 &generate_outfile;
489 else {
490 system("gzip $dbgoutfile");
493 elsif ($outfile ne "no file" and $dbgoutfile eq "no file") {
494 if ($pid=fork()) {
496 elsif (defined $pid) {
497 close(0);close(1);close(2);
498 exec "echo quit | $wineloc -debugmsg $debugopts $extraops \"$program\" 2>&1| tee $tmpoutfile | tail -n $lastnlines > $outfile";
500 else {
501 die "couldn't fork";
503 print "$outfile $tmpoutfile";
504 while (kill(0, $pid)) {
505 sleep(5);
506 $last = `tail -n 5 $tmpoutfile | grep Wine-dbg`;
507 if ($last =~ /Wine-dbg/) {
508 kill "TERM", $pid;
509 break;
512 unlink($tmpoutfile);
513 open(OUTFILE, "$outfile");
514 while (<OUTFILE>) {
515 $lastlines .= $_;
517 close(OUTFILE);
518 unlink($outfile);
519 &generate_outfile;
521 else {
522 $var27 = qq{
523 I guess you don't want me to make any debugging output. I'll send
524 it to your terminal. This will be a *lot* of output -- hit enter to
525 continue, control-c to quit.
526 Repeat: this will be a lot of output!
528 print do_var($var27);
529 $blah=<STDIN>;
530 system("$wineloc -debugmsg $debugmsg $extraops \"$program\"");
532 sub generate_outfile {
533 open(OUTFILE,">$outfile");
534 print OUTFILE <<EOM;
535 Auto-generated debug report by Wine Quick Debug Report Maker Thingy:
536 WINE Version: $winever
537 Windows Version: $winver
538 Distribution: $dist
539 Kernel Version: $kernelver
540 OS Type: $ostype
541 CPU: $cpu
542 GCC Version: $gccver
543 Program: $progname
544 Program Type: $progbits
545 Debug Options: -debugmsg $debugopts
546 Other Extra Commands Passed: $extraops
547 Extra ./configure Commands: $configopts
548 Wine Dependencies:
549 $wineneeds
550 Last $lastnlines lines of debug output follows:
551 $lastlines
552 I have a copy of the full debug report, if it is needed.
553 Thank you!
556 $var22 = qq{
557 Great! We're finished making the debug report. Do whatever with it.
559 $var28 = qq{
560 The filename for the formatted report is:
561 $outfile
563 $var29 = qq{
564 The filename for the compressed full debug is:
565 $dbgoutfile.gz
566 Note that it is $dbgoutfile.gz, since I compressed it with gzip for you.
568 $var30 = qq{
569 Having problems with the script?
570 Submit a bug report to Wine bugtracking system at http://bugs.winehq.com or
571 tell the wine newsgroup (comp.emulators.ms-windows.wine).
573 print do_var($var22);
574 print do_var($var28) if $outfile ne "no file";
575 print do_var($var29) if $dbgoutfile ne "no file";
576 print do_var($var30);