bug_report.pl 17 KB
Newer Older
1
#!/usr/bin/perl -w
2
##Wine Quick Debug Report Maker Thingy (WQDRMK)
3
## Copyright (c) 1998-1999 Adam Sacarny jazz@cscweb.net ICQ: 19617831
4 5
##Do not say this is yours without my express permisson, or I will
##hunt you down and kill you like the savage animal I am.
6 7 8 9
##
## Improvements by Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
## (c) 2000
##
10
## A few improovements and updates here and there
11
## Copyright 2003-2004 Ivan Leo Puoti
12
##
13 14 15 16 17 18 19 20 21 22 23 24 25
## This library is free software; you can redistribute it and/or
## modify it under the terms of the GNU Lesser General Public
## License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public
## License along with this library; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
##
27
##Changelog:
28 29
##August 29, 1999 - Work around for debugger exit (or lack thereof)
##                - Should now put debugging output in correct place
30
##April 19, 1999 - Much nicer way to select Wine's location
31 32
##               - Option to disable creation of a debugging output
##               - Now places debugging output where it was started
33 34
##April 4, 1999 - Sanity check for file locations/wine strippedness
##              - Various code cleanups/fixes
35 36
##March 21, 1999 - Bash 2.0 STDERR workaround (Thanks Ryan Cumming!)
##March 1, 1999 - Check for stripped build
37 38
##February 3, 1999 - Fix to chdir to the program's directory
##February 1, 1999 - Cleaned up code
Adam the Jazz Guy's avatar
Adam the Jazz Guy committed
39 40 41
##January 26, 1999 - Fixed various bugs...
##                 - Made newbie mode easier
##January 25, 1999 - Initial Release
42 43 44
use strict;
sub do_var($) {
	my $var=$_[0];
45 46 47
	$var =~ s/\t//g;
	return $var;
}
48
open STDERR, ">&SAVEERR"; open STDERR, ">&STDOUT";
Adam the Jazz Guy's avatar
Adam the Jazz Guy committed
49
$ENV{'SHELL'}="/bin/bash";
50
my $var0 = qq{
51
	What is your level of Wine expertise? 1-newbie 2-intermediate 3-advanced
52

53
	1 - Makes a debug report as defined in the Wine documentation. Best
54
	    for new Wine users. If you're not sure what WINEDEBUG is, then
55
	    use this mode.
56
	2 - Makes a debug report that is more customizable (Example: you can
57
	    choose what WINEDEBUG to use). You are asked more questions in
58
	    this mode. May intimidate newbies.
59
	3 - Just like 2, but not corner cutting. Assumes you know what you're
60
	    doing so it leaves out the long descriptions.
61
};
62
print do_var($var0)."\n";
63
my $debuglevel=0;
64
until ($debuglevel >= 1 and $debuglevel <= 3) {
65
	print "Enter your level of Wine expertise (1-3): ";
66 67
	$debuglevel=<STDIN>;
	chomp $debuglevel;
68
}
69

70
if ($debuglevel < 3) {
71
	my $var1 = qq{
72
	This program will make a debug report for Wine developers. It generates
73 74 75
	two files. The first one has everything asked for by the bugreports guide;
	the second has *all* of the debug output, which can go to thousands of
	lines.
76
	To (hopefully) get the bug fixed, report it to the project
77
	bug tracking system at http://bugs.winehq.org.
78 79
	Attach the first file to the bug description.
	Also include detailed description of the problem. The developers
80 81 82 83
	might ask you for "the last X lines from the report". If so, just
	provide the output of the following command:
	    gzip -d (output file) | tail -n (X) > outfile
	If you do not want to create one of the files, just specify "no file".
84 85 86
	};
	print do_var($var1);
} elsif ($debuglevel =~ 3) {
87
	my $var2 = qq{
88 89 90 91
	This program will output to two files:
	1. Formatted debug report you might want to post to the newsgroup
	2. File with ALL the debug output (It will later be compressed with
	gzip, so leave off the trailing .gz)
92 93
	If you do not want to create one of the files, just type in "no file"
	and I'll skip it.
94 95
	};
	print do_var($var2);
96
}
97 98

print "\nFilename for the formatted debug report: ";
99
my $outfile=<STDIN>;
100
chomp $outfile;
101
my $var23 = qq{
102 103 104 105 106 107 108
I don't think you typed in the right filename. Let's try again.
};
while ($outfile =~ /^(\s)*$/) {
	print do_var($var23);
	$outfile=<STDIN>;
	chomp $outfile;
}
109 110

print "Filename for full debug output: ";
111
my $dbgoutfile=<STDIN>;
112
chomp $dbgoutfile;
113 114 115 116 117
while ($dbgoutfile =~ /^(\s)*$/) {
	print do_var($var23);
	$dbgoutfile=<STDIN>;
	chomp $dbgoutfile;
}
118

119
my $var31 = qq{
120 121 122 123 124
Since you will only be creating the formatted report, I will need a
temporary place to put the full output.
You may not enter "no file" for this.
Enter the filename for the temporary file:
};
125
my $tmpoutfile;
126 127 128 129 130 131 132 133 134 135
if ($outfile ne "no file" and $dbgoutfile eq "no file") {
	print do_var($var31);
	$tmpoutfile=<STDIN>;
	chomp $tmpoutfile;
	while (($tmpoutfile =~ /^(\s)*$/) or ($tmpoutfile eq "no file")) {
		print do_var($var23);
		$tmpoutfile=<STDIN>;
		chomp $tmpoutfile;
	}
}
136

137
my $whereis=`whereis wine`;
138
chomp $whereis;
139
print "\nWhere is your copy of Wine located?\n\n";
140
$whereis =~ s/^wine\: //;
141
my @locations = split(/\s/,$whereis);
142 143
print "1 - Unlisted (I'll prompt you for a new location\n";
print "2 - Unsure (I'll use #3, that's probably it)\n";
144 145
my $i=2;
foreach my $location (@locations) {
146
	$i++;
147
	print "$i - $location\n";
148
}
149
print "\n";
150 151
sub select_wineloc() {
	my $wineloc;
152 153
	do
		{
154 155 156
		print "Enter the number that corresponds to Wine's location: ";
		$wineloc=<STDIN>;
		chomp $wineloc;
157
		}
158
	while ( ! ( $wineloc >=1 and $wineloc <= 2+@locations ) );
159
	if ($wineloc == 1) {
160
		my $var25 = qq{
161
		Enter the full path to wine (Example: /usr/bin/wine):
162
		};
163
		my $var26 = qq{
164 165 166 167 168
		Please enter the full path to wine. A full path is the
		directories leading up to a program's location, and then the
		program. For example, if you had the program "wine" in the
		directory "/usr/bin", you would type in "/usr/bin/wine". Now
		try:
169
		};
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
		print do_var($var25) if $debuglevel == 3;
		print do_var($var26) if $debuglevel < 3;
		$wineloc=<STDIN>;
		chomp $wineloc;
		while ($wineloc =~ /^(\s)*$/) {
			print do_var($var23);
			$wineloc=<STDIN>;
			chomp $wineloc;
		}
	}
	elsif ($wineloc == 2) {
		$wineloc=$locations[0];
	}
	else {
		$wineloc=$locations[$wineloc-3];
185
	}
186
	return $wineloc;
187
}
188
my $wineloc=select_wineloc();
189
print "Checking if $wineloc is stripped...\n";
190
my $ifstrip = `nm $wineloc 2>&1`;
191
while ($ifstrip =~ /no symbols/) {
192
	my $var24 = qq{
193
	Your wine is stripped! Stripped versions make useless debug reports
194
	If you have another location of wine that may be used, enter it now.
195 196
	Otherwise, hit control-c and download an unstripped (Debug) version, then re-run
	this script.
197 198
	};
	print do_var($var24);
199
	$wineloc=select_wineloc();
200 201 202
	$ifstrip = `nm $wineloc 2>&1`;
}
while ($ifstrip =~ /not recognized/) {
203
	my $var26 = qq{
204
	Looks like you gave me something that isn't a Wine binary (It could be a
205 206 207
	text file). Try again.
	};
	print do_var($var26);
208
	$wineloc=select_wineloc();
209
	print "Checking if $wineloc is stripped...\n";
210
	$ifstrip = `nm $wineloc 2>&1`;
211
}
212

213
print "\nWhat version of Windows are you using with Wine?\n\n".
214 215 216 217
      "0 - None\n".
      "1 - Windows 3.x\n".
      "2 - Windows 95\n".
      "3 - Windows 98\n".
218 219 220 221 222 223 224
      "4 - Windows ME\n".
      "5 - Windows NT 3.5x\n".
      "6 - Windows NT4.x\n".
      "7 - Windows 2000\n".
      "8 - Windows XP\n".
      "9 - Windows Server 2003\n".
      "10 - Other\n\n";
225
my $winver;
226 227
do
	{
228
	print "Enter the number that corresponds to your Windows version: ";
229 230
	$winver=<STDIN>;
	chomp $winver;
231
	}
232
until ($winver >= 0 and $winver <= 10);
233 234 235 236 237 238 239 240 241
if ($winver =~ 0) {
	$winver="None Installed";
} elsif ($winver =~ 1) {
	$winver="Windows 3.x";
} elsif ($winver =~ 2) {
	$winver="Windows 95";
} elsif ($winver =~ 3) {
	$winver="Windows 98";
} elsif ($winver =~ 4) {
242
	$winver="Windows ME";
243
} elsif ($winver =~ 5) {
244
	$winver="Windows NT 3.5x";
245
} elsif ($winver =~ 6) {
246
	$winver="Windows NT 4.x";
247
} elsif ($winver =~ 7) {
248
	$winver="Windows 2000";
249
} elsif ($winver =~ 8) {
250 251 252 253
	$winver="Windows XP";
} elsif ($winver =~ 9) {
	$winver="Windows Server 2003";
} elsif ($winver =~ 10) {
254
	print "What version of Windows are you using? ";
255 256
	$winver=<STDIN>;
	chomp $winver;
257
}
258
if ($debuglevel < 3) {
259
	my $var7 = qq{
260 261 262 263 264 265
	Enter the full path to the program you want to run. Remember what you
	were told before - a full path is the directories leading up to the
	program and then the program's name, like /dos/windows/sol.exe, not
	sol.exe:
	};
	print do_var($var7);
266 267
}
if ($debuglevel =~ 3) {
268
	my $var8 = qq{
269 270
	Enter the full path to the program you want to run (Example:
	/dos/windows/sol.exe, NOT sol.exe):
271 272
	};
	print do_var($var8);
273
}
274
my $program=<STDIN>;
275
chomp $program;
276 277 278 279 280 281
while ($program =~ /^(\s)*$/) {
	print do_var($var23);
	$program=<STDIN>;
	chomp $program;
}
$program =~ s/\"//g;
282
my $var9 = qq{
283 284
Enter the name, version, and manufacturer of the program (Example:
Netscape Navigator 4.5):
285 286
};
print do_var($var9);
287
my $progname=<STDIN>;
288
chomp $progname;
289
my $var10 = qq{
290 291
Enter 1 if your program is 16 bit (Windows 3.x), 2 if your program is 32
bit (Windows 95, NT3.x and up), or 3 if you are unsure:
292 293
};
print do_var($var10);
294
my $progbits=<STDIN>;
295
chomp $progbits;
296 297
until ($progbits == 1 or $progbits == 2 or $progbits == 3) {
	print "You must enter 1, 2 or 3!\n";
298
	$progbits=<STDIN>;
299
	chomp $progbits
300
}
301
if ($progbits =~ 1) {
302
	$progbits = "Win16";
303
} elsif ($progbits =~ 2) {
304
	$progbits = "Win32";
305
} else {
306
	$progbits = "Unsure";
307
}
308
my $debugopts;
309
if ($debuglevel > 1) {
310
	if ($debuglevel =~ 2) {
311
		my $var11 = qq{
312 313
		Enter any extra debug options. Default is +relay - If you don't
		know what options to use, just hit enter, and I'll use those (Example, the
314
		developer tells you to re-run with WINEDEBUG=+dosfs,+module you would type
315 316 317 318
		in +dosfs,+module). Hit enter if you're not sure what to do:
		};
		print do_var($var11);
	} elsif ($debuglevel =~ 3) {
319
		my $var12 = qq{
320
		Enter any debug options you would like to use. Just enter parts after
321
		WINEDEBUG. Default is +relay:
322 323 324 325 326
		};
		print do_var($var12);
	}
	$debugopts=<STDIN>;
	chomp $debugopts;
327
	if ($debugopts =~ /--debugmsg /) {
328 329
		$debugopts = (split / /,$debugopts)[1];
	}
Ivan Leo Murray-Smith's avatar
Ivan Leo Murray-Smith committed
330
	if ($debugopts =~ /WINEDEBUG= /) {
331
		$debugopts = (split / /,$debugopts)[1];
332 333 334
	}
	if ($debugopts =~ /^\s*$/) {
		$debugopts="+relay";
335 336
	}
} elsif ($debuglevel =~ 1) {
337 338
	$debugopts = "+relay";
}
339
my $lastnlines;
Adam the Jazz Guy's avatar
Adam the Jazz Guy committed
340
if ($debuglevel > 1) {
341
	if ($debuglevel =~ 2) {
342
		my $var13 = qq{
343 344
		How many trailing lines of debugging info do you want to include in the report
		you're going to submit (First file)? If a developer asks you to include
345
		the last 15000 lines, enter 15000 here. Default is 3000, which is reached by
346 347 348 349
		pressing enter. (If you're not sure, just hit enter):
		};
		print do_var($var13);
	} elsif ($debuglevel =~ 3) {
350
		my $var14 = qq{
351
		Enter how many lines of trailing debugging output you want in your nice
352
		formatted report. Default is 3000:
353 354 355 356 357
		};
		print do_var($var14);
	}
	$lastnlines=<STDIN>;
	chomp $lastnlines;
358
	if ($lastnlines =~ /^\s*$/) {
359
	$lastnlines=3000;
360
	}
361
} elsif ($debuglevel =~ 1) {
362
	$lastnlines=3000;
Adam the Jazz Guy's avatar
Adam the Jazz Guy committed
363
}
364
my $extraops;
365
if ($debuglevel > 1) {
366
	my $var15 = qq{
367
	Enter any extra options you want to pass to Wine.
368 369 370 371 372
	};
	print do_var($var15);
	$extraops=<STDIN>;
	chomp $extraops;
} elsif ($debuglevel =~ 1) {
373
	$extraops=" ";
Adam the Jazz Guy's avatar
Adam the Jazz Guy committed
374
}
375

376
print "\nEnter the name of your distribution (Example: RedHat 9.0): ";
377
my $dist=<STDIN>;
378
chomp $dist;
379

380
my $configopts;
381
if ($debuglevel > 1) {
382
	if ($debuglevel =~ 2) {
383
		my $var16 = qq{
384 385
		When you ran ./configure to build wine, were there any special options
		you used to do so (Example: --enable-dll)? If you didn't use any special
386
		options or didn't compile Wine yourself, just hit enter:
387 388 389
		};
		print do_var($var16);
	} elsif ($debuglevel =~ 3) {
390
		my $var17 = qq{
391 392
		Enter any special options you used when running ./configure for Wine
		(Default is none, use if you didn't compile Wine yourself):
393 394 395 396 397
		};
		print do_var($var17);
	}
	$configopts=<STDIN>;
	chomp $configopts;
398 399 400
	if ($configopts =~ /^\s*$/) {
	$configopts="None";
	}
401
} elsif ($debuglevel =~ 1) {
402
	$configopts="None";
403
}
404
my $winever;
405
if ($debuglevel > 1) {
406
	if ($debuglevel =~ 2) {
407
		my $var18 = qq{
408
		Is your Wine version CVS or from a .tar.gz or RPM file? As in... did you download it
409
		off a website/ftpsite or did you/have you run cvs on it to update it?
410 411
		For CVS: YYYYMMDD, where YYYY is the year (2004), MM is the month (03), and DD
		is the day (09), that you last updated it (Example: 20040309).
412
		For tar.gz and RPM: Just hit enter and I'll figure out the version for you:
413 414 415
		};
		print do_var($var18);
	} elsif ($debuglevel =~ 3) {
416
		my $var19 = qq{
417
		Is your Wine from CVS? Enter the last CVS update date for it here, in
418
		YYYYMMDD form (If it's from a tarball or RPM, just hit enter):
419 420 421 422 423
		};
		print do_var($var19);
	}
	$winever=<STDIN>;
	chomp $winever;
424
	if ($winever =~ /[0-9]+/) {
425 426 427 428 429
		$winever .= " CVS";
	}
	else {
		$winever = `$wineloc -v 2>&1`;
		chomp $winever;
430
	}
431 432 433
} elsif ($debuglevel =~ 1) {
	$winever=`$wineloc -v 2>&1`;
	chomp $winever;
434
}
435 436
my $gccver=`gcc -v 2>&1`;
$gccver = (split /\n/,$gccver)[1];
437
chomp $gccver;
438
my $cpu=`uname -m`;
439
chomp $cpu;
440
my $kernelver=`uname -r`;
441
chomp $kernelver;
442
my $ostype=`uname -s`;
443
chomp $ostype;
444
my $wineneeds=`ldd $wineloc`;
445
if ($debuglevel < 3) {
446
	my $var20 = qq{
447
	OK, now I'm going to run Wine. I will close it for you once the Wine
448 449
	debugger comes up. NOTE: You won't see ANY debug messages. Don't
	worry, they are being output to a file. Since there are so many, it's
450
	not a good idea to have them all output to a terminal (Speed slowdown
451
	mainly).
452
	Wine will still run much slower than normal, because there will be so
453
	many debug messages being output to file.
454 455 456
	};
	print do_var($var20);
} elsif ($debuglevel =~ 3) {
457
	my $var21 = qq{
458
	OK, now it's time to run Wine. I will close down Wine for you after
459 460 461
	the debugger is finished doing its thing.
	};
	print do_var($var21);
462
}
463
print "Hit enter to start Wine!\n";
464 465
<STDIN>;
my $dir=$program;
466 467
$dir=~m#(.*)/#;
$dir=$1;
468
use Cwd;
469
my $nowdir=getcwd;
470
chdir($dir);
471 472
if (!($outfile =~ /\//) and $outfile ne "no file") {
	$outfile = "$nowdir/$outfile";
473
}
474 475 476 477 478 479 480
if (!($dbgoutfile =~ /\//) and $dbgoutfile ne "no file") {
	$dbgoutfile = "$nowdir/$dbgoutfile";
}
if (!($tmpoutfile =~ /\//)) {
	$tmpoutfile = "$nowdir/$tmpoutfile";
}
$SIG{CHLD}=$SIG{CLD}=sub { wait };
481 482
my $lastlines;
sub generate_outfile();
483 484
if ($dbgoutfile ne "no file") {
	unlink("$dbgoutfile");
485 486
	my $pid=fork();
	if ($pid) {
487 488 489
	}
	elsif (defined $pid) {
		close(0);close(1);close(2);
490
		exec "echo quit | WINEDEBUG=$debugopts $wineloc $extraops \"$program\" > $dbgoutfile 2>&1";
491 492 493 494 495 496
	}
	else {
		die "couldn't fork";
	}
	while (kill(0, $pid)) {
		sleep(5);
497
		my $last = `tail -n 5 $dbgoutfile | grep Wine-dbg`;
498 499
		if ($last =~ /Wine-dbg/) {
			kill "TERM", $pid;
500
			last;
501 502 503 504 505
		}
	}
	if ($outfile ne "no file") {
		$lastlines=`tail -n $lastnlines $dbgoutfile`;
		system("gzip $dbgoutfile");
506
		generate_outfile();
507 508 509 510
	}
	else {
		system("gzip $dbgoutfile");
	}
511
}
512
elsif ($outfile ne "no file" and $dbgoutfile eq "no file") {
513 514
	my $pid=fork();
	if ($pid) {
515 516 517
	}
	elsif (defined $pid) {
		close(0);close(1);close(2);
518
		exec "echo quit | WINEDEBUG=$debugopts $wineloc $extraops \"$program\" 2>&1| tee $tmpoutfile | tail -n $lastnlines > $outfile";
519 520 521 522 523 524 525
	}
	else {
		die "couldn't fork";
	}
	print "$outfile $tmpoutfile";
	while (kill(0, $pid)) {
		sleep(5);
526
		my $last = `tail -n 5 $tmpoutfile | grep Wine-dbg`;
527 528
		if ($last =~ /Wine-dbg/) {
			kill "TERM", $pid;
529
			last;
530 531 532 533 534 535 536 537 538
		}
	}
	unlink($tmpoutfile);
	open(OUTFILE, "$outfile");
	while (<OUTFILE>) {
		$lastlines .= $_;
	}
	close(OUTFILE);
	unlink($outfile);
539
	generate_outfile();
540 541
}
else {
542
	my $var27 = qq{
543 544 545 546 547 548
	I guess you don't want me to make any debugging output. I'll send
	it to your terminal. This will be a *lot* of output -- hit enter to
	continue, control-c to quit.
	Repeat: this will be a lot of output!
	};
	print do_var($var27);
549
	<STDIN>;
550
	system("$wineloc WINEDEBUG=$debugopts $extraops \"$program\"");
551
}
552
sub generate_outfile() {
553
open(OUTFILE,">$outfile");
554
print OUTFILE <<EOM;
555
Auto-generated debug report by Wine Quick Debug Report Maker Tool:
556 557 558 559 560 561 562 563 564
WINE Version:                $winever
Windows Version:             $winver
Distribution:                $dist
Kernel Version:              $kernelver
OS Type:                     $ostype
CPU:                         $cpu
GCC Version:                 $gccver
Program:                     $progname
Program Type:                $progbits
565
Debug Options:               WINEDEBUG=$debugopts
566 567
Other Extra Commands Passed: $extraops
Extra ./configure Commands:  $configopts
568
Wine Dependencies:
569 570 571 572 573 574
$wineneeds
Last $lastnlines lines of debug output follows:
$lastlines
I have a copy of the full debug report, if it is needed.
Thank you!
EOM
575
}
576
my $var22 = qq{
577
Great! We're finished making the debug report. Please go to http://bugs.winehq.org
578
and enter it as a new bug. Check that nobody has already reported the same bug!
579
};
580
my $var28 = qq{
581
The filename for the formatted report is:
582
$outfile
583
};
584
my $var29 = qq{
585 586 587
The filename for the compressed full debug is:
$dbgoutfile.gz
Note that it is $dbgoutfile.gz, since I compressed it with gzip for you.
588
};
589
my $var30 = qq{
590
If you have any problems with this bug reporting tool,
591
please submit a bug report to Wine bugtracking system at http://bugs.winehq.org
592
or tell the Wine newsgroup (comp.emulators.ms-windows.wine).
593 594
};
print do_var($var22);
595 596 597
print do_var($var28) if $outfile ne "no file";
print do_var($var29) if $dbgoutfile ne "no file";
print do_var($var30);