|
From: <dom...@fr...> - 2006-03-16 11:52:54
|
I have built the allegro library (a game C lib) available at... http://alleg.sourceforge.net/wip.html ... along with the 'demo' program that comes with it. I can run the allegro demo without valgrind without problem. However, if I try to run the demo with valgrind using memcheck, I get the following errors: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D $ /usr/local/bin/valgrind --tool=3Dmemcheck ~/allegro4.1-4.1.15/demo/demo [...snip...] vex x86->IR: unhandled instruction bytes: 0x6 0x8E 0x42 0x3C =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D If I try leak-check tool, I get the same error + an assertion failure: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D $ /usr/local/bin/valgrind --leak-check=3Dyes ~/allegro4.1-4.1.15/demo/dem= o [...snip...] vex x86->IR: unhandled instruction bytes: 0x6 0x8E 0x42 0x3C [...snip...] Shutting down Allegro due to signal #4 not in syscall (0xB0044BBC - 0xB0044C11) valgrind: m_syswrap/syswrap-main.c:606 (vgPlain_client_syscall): Assertio= n 'sci->status.what =3D=3D SsIdle' failed. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D I'm using: $ /usr/local/bin/valgrind --version valgrind-3.1.1 $ uname -a Linux mylnxbox 2.6.12-10-386 #1 Sat Mar 11 16:13:17 UTC 2006 i686 GNU/Lin= ux $ cat /proc/cpuinfo processor : 0 vendor_id : AuthenticAMD cpu family : 6 model : 2 model name : AMD Athlon(tm) Processor stepping : 1 cpu MHz : 700.260 cache size : 512 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 1 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 sep mtrr pge mca cmo= v pat pse36 mmx fxsr syscall mmxext 3dnowext 3dnow bogomips : 1384.44 |
|
From: <dom...@fr...> - 2006-03-16 21:24:11
|
Thanks for your reply. Agreed, I was using an old version of allegro. I was actually using the source package that comes with Ubuntu-5.10. I can successfully build the latest allegro-4.2 but allegro demo then does not work for me (init fails) for reasons I cannot fathom yet. Allegro-4.1.x at least works for me except when I try to use it with valgrind-3.1.1. Anyway, valgrind-3.1.1 should in theory work even with an old version of allegro. The valgrind assert() failure in particular should be a bug. I also thought about using 'configure --disable-asm' to build allegro but then build fails (link error) I will try to investigate it further later when I have more time. Cheers /Dominique Quoting Serge Semashko <se...@lx...>: > dom...@fr... wrote: > > First you are using very old allegro version, the most up to date > version is 4.2.0 > > Second, if you want to valgrind it, it is better to configure it as: > ./configure --disable-asm > > Depending on what you want to achieve, this information might be > enough :) [..snip...] > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > $ /usr/local/bin/valgrind --leak-check=3Dyes ~/allegro4.1-4.1.15/demo/d= emo > [...snip...] > vex x86->IR: unhandled instruction bytes: 0x6 0x8E 0x42 0x3C > [...snip...] > Shutting down Allegro due to signal #4 > not in syscall (0xB0044BBC - 0xB0044C11) > > valgrind: m_syswrap/syswrap-main.c:606 (vgPlain_client_syscall): Assert= ion > 'sci->status.what =3D=3D SsIdle' failed. > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [...snip...] > $ /usr/local/bin/valgrind --version > valgrind-3.1.1 |
|
From: Julian S. <js...@ac...> - 2006-03-18 11:34:58
|
> vex x86->IR: unhandled instruction bytes: 0x6 0x8E 0x42 0x3C I fixed this (in the svn trunk; not 3.1.1) just now (r1600) but demo/demo for allegro-4.2.0 still segfaults for some reason. Don't know why. J |
|
From: <dom...@fr...> - 2006-03-18 23:43:10
|
Thanks Julian, I just downloaded the latest version of valgrind from SVN (r1600) after your change. I observe the exact same behavior as you describe, using allegro-4.1.15 that comes with Ubuntu-5.10. To sum up: * without valgrind, allegro demo-4.1.15 works fine * with valgrind-3.1.1, allegro demo reports vex x86->IR: unhandled instruction bytes: 0x6 0x8E 0x42 0x3C and exits * With valgrind SVN r1600, allegro demo no longer reports unhandled instruction but segfaults. Cheers /Dominique Quoting Julian Seward <js...@ac...>: > > > vex x86->IR: unhandled instruction bytes: 0x6 0x8E 0x42 0x3C > > I fixed this (in the svn trunk; not 3.1.1) just now (r1600) > but demo/demo for allegro-4.2.0 still segfaults for some reason. > Don't know why. > > J |
|
From: Julian S. <js...@ac...> - 2006-03-19 12:42:32
|
> * With valgrind SVN r1600, allegro demo no longer reports > unhandled instruction but segfaults. I've looked at this some more. It is to do with the use of %es: segment overrides in _linear_putpixel, and specifically this towards the end: 26 88 1c 08 mov %bl,%es:(%eax,%ecx,1) Valgrind simulates the LDT/GDT directly and so computes linear addresses from virtual addresses (I think I have the jargon correct here). Anyway, it looks in the process' LDT at the entry indicated by %es, to get the right offset. This mechanism is known to work OK since most threaded programs on Linux require segment overriding to work properly. Anyway: Valgrind computes the linear address, and decides it is invalid for some reason, so it whacks the program with a segmentation fault, which is what you saw. I have an idea why this happened. How does the application set the LDT entry it wants to use (which is 0x7B >> 3 ?) I don't know. It should do a modify_ldt syscall, but I don't see any of those. Valgrind builds its picture of the program's LDT by intercepting this syscall, but I don't see any such syscalls in the log (--trace-syscalls=yes). If you want to help track this down, go figure out how/where the LDT entry is set. Obviously something's not right with V since the program runs fine on my SuSE 10 box when not running on V. J |
|
From: Julian S. <js...@ac...> - 2006-03-19 13:32:47
|
> I have an idea why this happened. How does the application set > the LDT entry it wants to use (which is 0x7B >> 3 ?) In fact it's a GDT entry, not an LDT entry, and Valgrind believes the .limit field of the entry is zero, which is why it issues a segfault. This probably means V thinks the GDT entry has never been set. I have no idea how/where in Allegro the GDT entry is set. J |
|
From: John R.
|
Julian Seward wrote: >>I have an idea why this happened. How does the application set >>the LDT entry it wants to use (which is 0x7B >> 3 ?) > > > In fact it's a GDT entry, not an LDT entry, and Valgrind believes > the .limit field of the entry is zero, which is why it issues > a segfault. This probably means V thinks the GDT entry has never > been set. I have no idea how/where in Allegro the GDT entry is set. Valgrind should assume that each segment in the GDT starts with a .limit of 0xfffff, and it's in pages (not bytes) and is inclusive. This means that Valgrind might as well not check .limit of GDT segments. In a segment descriptor, a 0 in bit 0 (the low-order bit) signifies GDT. The operating system kernel sets the GDT all by itself, and provides no means for the user to read its contents. Linux uses only a couple fixed GDT entries per process (see USER_CS and USER_DS in linux/include/asm-i386/processor.h) but the constants can change from time to time [especially from distro to distro, Win4Lin, etc.] -- John Reiser, jreiser@BitWagon.com |
|
From: John R.
|
> In a segment descriptor, a 0 in bit 0 (the low-order bit) signifies GDT. Oops. The GDT/LDT bit in a segment selector is bit 2 with place value (1<<2) or 4. 0 means GDT, 1 means LDT. Bits 1:0 are the privilege level: 0 for kernel, 3 for user, etc. -- John Reiser, jreiser@BitWagon.com |
|
From: Julian S. <js...@ac...> - 2006-03-20 01:04:16
|
> The operating system kernel sets the GDT all by itself, > and provides no means for the user to read its contents. > Linux uses only a couple fixed GDT entries per process > (see USER_CS and USER_DS in linux/include/asm-i386/processor.h) > but the constants can change from time to time [especially > from distro to distro, Win4Lin, etc.] Fine, but how can it be that this Allegro library is using GDT entries in a meaningful way if it doesn't have any way to somehow specify the contents of the GDT entry it is using? I don't understand that. J |
|
From: John R.
|
Julian Seward wrote: > Fine, but how can it be that this Allegro library is using GDT > entries in a meaningful way if it doesn't have any way to > somehow specify the contents of the GDT entry it is using? It seems to me that this "Allegro" package, being an environment for "video arcade" games, might be manipulating the hardware directly. In particular, the VGA hardware as "borrowed" from X11. The segment register(s) probably designate the VGA physical video memory. From http://alleg.sourceforge.net/wip.html I downloaded and built allegro-4.2.0.tar.gz which is not the same version as the original poster in this thread. I ran it and clicked a few default responses, then it started running a full-screen "teaser" to get me to deposit my $0.25 coin [;-)] and start playing the game. <ESC> got me out. Under valgrind-3.1.1, I see: ----- $ valgrind --db-attach=yes ./demo ==20077== Memcheck, a memory error detector. ==20077== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al. ==20077== Using LibVEX rev 1575, a library for dynamic binary translation. ==20077== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP. ==20077== Using valgrind-3.1.1, a dynamic binary instrumentation framework. ==20077== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al. ==20077== For more details, rerun with: -v ==20077== vex x86->IR: unhandled instruction bytes: 0x66 0x6 0x8B 0x55 ==20077== Your program just tried to execute an instruction that Valgrind ==20077== did not recognise. There are two possible reasons for this. ==20077== 1. Your program has a bug and erroneously jumped to a non-code ==20077== location. If you are running Memcheck and you just saw a ==20077== warning about a bad jump, it's probably your program's fault. ==20077== 2. The instruction is legitimate but Valgrind doesn't handle it, ==20077== i.e. it's Valgrind's fault. If you think this is the case or ==20077== you are not sure, please let us know. ==20077== Either way, Valgrind will now raise a SIGILL signal which will ==20077== probably kill your program. Shutting down Allegro due to signal #4 not in syscall (0xB0041A30 - 0xB0041A85) ==20077== ==20077== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- y ==20077== starting debugger with cmd: /usr/bin/gdb -nw /proc/20081/fd/1014 20081 [snip] Attaching to program: /proc/20081/fd/1014, process 20081 Reading symbols from shared object read from target memory...(no debugging symbols found)...done. Loaded system supplied DSO at 0x602000 `shared object read from target memory' has disappeared; keeping its symbols. 0xb001b7c1 in ?? () (gdb) info reg eax 0x0 0x0 ecx 0x4e6d 0x4e6d edx 0x4 0x4 ebx 0x4e6d 0x4e6d esp 0xbe891f1c 0xbe891f1c ebp 0xbe891f2c 0xbe891f2c esi 0x4 0x4 edi 0xdccff4 0xdccff4 eip 0xb001b7c1 0xb001b7c1 eflags 0x200202 0x200202 cs 0x73 0x73 ss 0x7b 0x7b ds 0x7b 0x7b es 0x0 0x0 fs 0x0 0x0 gs 0x621c0003 0x621c0003 (gdb) ----- So, on to debugging: 1. WHAT THE !@#$% IS THE VALUE OF THE PC where the unhandled bytes reside? This ESSENTIAL piece of information is nowhere to be found! I'd like to look at the instruction stream just before and after, identify which module (main or shared library) is responsible, etc. 2. Assuming that the bytes "0x66 0x6 0x8b 0x55" really are the instruction stream, then the instruction is "pushw %es". From "(gdb) info reg" %es is 0, the initial value. So the code isn't banging the hardware yet. 3. I tracked down a plausible module by: (gdb) info proc (gdb) shell cat /proc/<pid>/maps $ for i in $(cat mapped-module-pathnames) > do echo $i; objdump --disassemble $i | grep "06 8e"; done which reveals that ./demo contains 08056098 <_linear_putpixel16>: 8056098: 55 push %ebp 8056099: 89 e5 mov %esp,%ebp 805609b: 53 push %ebx 805609c: 66 06 pushw %es 805609e: 8b 55 08 mov 0x8(%ebp),%edx Clearly this is saving state in order to muck with the VGA hardware. This routine, or some subroutine, will set %es to a descriptor which maps VGA memory, modify that [video] memory [and hence the display], then restore %es upon exit. So the first answer is that it is the VGA *physical* memory segment. There are three of them: 64KB from 0xA0000-0xAFFFF for color graphics, 32KB from 0xB8000-0xBFFFF for color text, and 32KB from 0xB0000-0xB7FFF for monochrome text. The color graphics is bank-switched (eight 64KB banks) using control registers which appear in I/O space. Each bank is a single bitplane. To write a single 8-bit pixel requires changing the bank register 8 times, although obviously writing adjacent pixels is done so as to require switching banks only 8 times total instead of 8 times for each pixel. -- |
|
From: Nicholas N. <nj...@cs...> - 2006-03-21 04:17:17
|
On Sun, 19 Mar 2006, John Reiser wrote: > vex x86->IR: unhandled instruction bytes: 0x66 0x6 0x8B 0x55 > ==20077== Your program just tried to execute an instruction that Valgrind > ==20077== did not recognise. There are two possible reasons for this. > > [...] > > 1. WHAT THE !@#$% IS THE VALUE OF THE PC where the unhandled bytes reside? > This ESSENTIAL piece of information is nowhere to be found! > I'd like to look at the instruction stream just before and after, > identify which module (main or shared library) is responsible, etc. I just committed a change that prints out the PC. It's untested, so it would be helpful if you could svn update and confirm it gives the right value. Thanks. Nick |