13

I'm getting a bug report that some functionality in some music-playing code in an external DLL (SDL_Mixer, in case it helps) that my program uses is raising EPrivilege. The DLL is written in C, so I can't get useful stack trace information out of it with MadExcept, and the problem is not reproducible on my end. And just to make things worse, I don't even know what EPrivilege is.

I've never seen it come up in my own code, there's very little information about it available online, and what there is is contradictory. (One explanation says it's raised by the OS if you try to do something with a limited account that requires privileges that aren't available, another says that it's raised by the CPU if you try to execute an instruction that's above your privilege level.)

Does anyone have an authoritative explanation for what causes EPrivilege? And does anyone have any idea how it could be raised by music-playing code on one Windows 7 64-bit machine under a non-admin account but not be raised when running the same code on my Windows 7 64-bit machine under a non-admin account?

Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477

3 Answers3

18

EPrivilege is raised when the hardware objects to you trying to run a privileged instruction in user mode. These privileged instructions are restricted to supervisor mode, a.k.a. ring 0.

The hardware raises the error and then the RTL catches it and maps it to a RTL exception, just like all the EExternal exceptions, e.g. EAccessViolation, EStackOverflow etc.

Admin rights are not relevant here. That is something that is enforced by the OS software. Instruction privilege is controlled at the hardware level.

You see such an error if you attempt to execute garbage (i.e. corrupted function pointer) which just happens to spell a privileged instruction. Memory corruption is the only sane explanation. Only compilers that target kernel mode code will emit privileged instructions.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Yeah, I figured it would be something like a corrupted function pointer. I just wish I knew how a function pointer can get corrupted on one system and not on another, when executing the same code on the same data files on the same OS. :( – Mason Wheeler Jun 24 '11 at 22:42
  • I'd like to add that memory corruption doesn't have to occur due to bugs in software. The only time I've encountered it turned out to be caused by faulty hardware. – Sertac Akyuz Jun 24 '11 at 22:45
  • @mason No two machines ever have exactly the same OS by the time you account for updates and third party software. – David Heffernan Jun 24 '11 at 22:49
  • @sertac That's certainly a possibility but presumably it would affect all programs indiscriminately? – David Heffernan Jun 24 '11 at 22:50
  • "Only **programmers** that target kernel mode code will emit privileged instructions." Fixed that for you. – Premature Optimization Jun 26 '11 at 06:29
  • It turned out to be related to an uninitialized buffer. Grr, stupid C code not zeroing things out for you when you malloc them... – Mason Wheeler Jun 29 '11 at 18:49
  • @Mason `GetMem` doesn't zero out either. – David Heffernan Jun 29 '11 at 18:55
  • @David: Yeah, but when's the last time you used `GetMem`? Calling SetLength on an array, or a constructor on an object, does zero out the memory, and those are what I'm used to when it comes to allocation. – Mason Wheeler Jun 29 '11 at 18:57
  • @Mason Well it's once in a blue moon that I call `GetMem`. If I want it zeroed I just call `AllocMem`. – David Heffernan Jun 29 '11 at 19:05
10

We do a lot of real-time hardware control using Delphi. This involves reading and writing I/O ports. If you dont have permission (or a kernel driver) to do this, you get EPrivilege.

For example this bit of code:

procedure   WriteIOByte( AData : byte; AAddress : word); assembler;
asm
  out dx,al
end;

under W98 needed nothing to allow it to write a byte to an I/O address, eg the PC parallel port. Under NT and on it will generate EPrivilege unless that address has been 'opened' in some way eg using gwiopm. Thus EPrivilege can be an indicator of a 'garbage read/write' (as David suggests) or of an incomplete setup that read / writes incorrectly setup hardware.

Fabrizio
  • 7,603
  • 6
  • 44
  • 104
Brian Frost
  • 13,334
  • 11
  • 80
  • 154
  • This is perfectly true since Win 9x didn't make use of hardware rings but in 2011 it's pretty unlikely that Mason is running code that intentionally executes privileged instructions so I doubt this is the explanation. – David Heffernan Jun 25 '11 at 11:23
0

In my case I just recompiled the main unit and it got fixed.