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