Understanding User and Kernel Mode

In Task Manager, Under the processes Tab, In the Column labeled Username there is usually a user called SYSTEM…i think this user is using the Kernel Mode
so, here is a little trick on How to RUN as SYSTEM
Could be Useful with some Immagination

GetTime: 20:25

*in cmd,type: at 20:26 /interactive taskmgr.exe
and wait, at 20:26 the task manager will pop up, but it is running in interactive mode

  • in the process tab kill/end task of explorer, u will only see then ur desktop image and the task manager
  • in the task manager click file–new task
    type explorer, press enter
    explorer will run, and u will be back to full windows mode,but logged in as SYSTEM

I Guess this will make your new processes as SYSTEM(Kernel)
Could be Pretty Useful in some situation

I can’t read memory without making an API call?

I believe the CPU/Memory System takes care of this by creating an interrupt to ask the OS where the memory is actually mapped. Some amount of caching is used to make it faster. There is no need to get the OS involved when the read is on the same page as the last one.

gogolo:
if you can circumvent the use exceptions why not go ahead : for
example in c# the TryParse () method is a good exception work-around

If I recall correctly, if you reflect TryParse() you get something like this:

bool TryParse (object obj)
{
try
{
return Bool.Parse(obj);
}
catch (e)
{
return false;
}
}

Jonathan Holland, I just looked at the code for System.Boolean’s TryParse with Reflector. You recall incorrectly.

Another notable case where code went from User to Kernal was with NT 4.0. The GDI Code went from being just another process to living in Kernal space. There was a long history behind why it was a process (partly related to how the OS could have different personas) but it was slow.

Seems to me like I remember Dave Cutler (architect of VAX VMS) having issues when hired at Microsoft to architect Windows NT.

He didn’t want any drivers to run in Ring 0, but was ultimately overruled - especially for graphics drivers.

Kernel Mode? User Mode? Never heard at all.
How do we choose in which mode our C/C#/Java Code is executed. From what I’ve read I guess that’s not even possible. When would there be a practical use of these modes? Show me a little code :slight_smile:
Would someone be so kind and explain a little more?

@ Joe Chung
could you post the reflection of TryParse().

gogole:

Joe is right, my memory was faulty. It happens on occasion heh.

public static bool TryParse(string value, out bool result)
{
result = false;
if (value != null)
{
if (“True”.Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = true;
return true;
}
if (“False”.Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = false;
return true;
}
if (m_trimmableChars == null)
{
char[] destinationArray = new char[string.WhitespaceChars.Length + 1];
Array.Copy(string.WhitespaceChars, destinationArray, string.WhitespaceChars.Length);
destinationArray[destinationArray.Length - 1] = ‘\0’;
m_trimmableChars = destinationArray;
}
value = value.Trim(m_trimmableChars);
if (“True”.Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = true;
return true;
}
if (“False”.Equals(value, StringComparison.OrdinalIgnoreCase))
{
result = false;
return true;
}
}
return false;
}

@Jonathan Holland

hey we all get things wrong sometimes .BTW where/how did you get the reflection of TryParse() .i’m still learning and don’t know much about reflection.

" Only rings 0 (Kernel) and 3 (User) are typically used".

For Windows, yes. This was a design decision during the original NT project. NT was going to run on multiple chips, not just x86. Some of those chips only had two privilege levels, so NT was designed to run with two, instead of four.

A pretty good summary, though you might have expanded on why it’s so “costly” to change modes.

Once upon a time Windows NT video drivers ran totally in User Mode. If the video system crashed the screen would just go black for a second and then redraw itself.

Microsoft switched them to Kernel Mode in version 4.0 in an attempt to increase performance and beat Novell and OS/2.

Hi Jeff,

Some people already pointed out the slight inaccuracies in your post. Just a couple of things to emphasize:

  • It is fair enough to say that practically all exceptions involve a trip to kernel mode. This is true for “native” Win32 exceptions (SEH), this is true for C++ exceptions (which are just a particular kind of SEH), this is also true for .NET exceptions (which are implemented on top of SEH).

  • It is NOT fair to say that a user-mode to kernel-mode trip is “really expensive”. It is not free, but there are things significantly worse than just this transition. After all, if it were “really expensive” then by definition all system calls would be “really expensive”, because all system calls involve a user-mode to kernel-mode transition. So while it does make sense to mention that there’s a cost associated with transitioning between protection rings, it’s unfair to say that it’s “really expensive”.

  • While it is true that WDF offers the ability to run particular kinds of drivers (mostly USB drivers) in user-mode through the use of UMDF, even this architecture involves the user of a kernel-mode reflector device which reflects API calls from user-mode through kernel-mode back to the user-mode driver. The reason for this is that applications still communicate with the device through the usual Win32 system calls (e.g. ReadFile, WriteFile, DeviceIoControl etc.), which go through the I/O manager in kernel mode. Besides, most drivers on a Vista box are STILL kernel-mode drivers, entirely implemented in kernel-mode with no user-mode components whatsoever. So this was rather unfair to say, too.

  • Note that you slightly contradict yourself by saying that the greatest benefit of user-mode is protecting the system from catastrophic failures, yet mentioning (as a good example) the fact that Microsoft has transitioned parts of IIS to the HTTP.SYS driver. From the aspect of fault isolation, it is NOT a smart thing to do. From the aspect of getting top performance (e.g. performing DMA for cached content instead of going to main memory) it IS a smart thing to do.

I think it would be great if you provided a clarifying post for some of these things, because currently what you wrote is rather confusing for people who aren’t familiar with the material in question.

Sasha

Sasha: Not everyone is using Microsoft Visual C++ on Windows.
Let’s assume for a minute that regular C++ exceptions in the above platform are implemented as SEH and require kernel mode transitions.

Other implementations of C++ on windows, and on other OSs do NOT require going through kernel mode.
Not to mention other languages. Do Haskell exceptions require going through the kernel? I doubt it. Same for Python. There’s usually no need for that.

However, Jeff really needs to update this post. It’s below his usual standard.

Got the C# version running. Jesus H. Christ. Those are incredible results.

38064 ms kernel, 89326 ms user, 5000000 exceptions

That’s three times slower than even VC++ on WOW!

But wait, maybe .NET itself is just rotten slow? To test that I’ve added another loop with regular “if” branches taken in alternation, and an Exception object created for each branch so we have the same load on the garbage collector. And here’s the result:

15 ms kernel, 140 ms user, 2500000 + 2500000 branches

Branching without exceptions is EIGHT HUNDRED TIMES faster than executing a try-catch block! I tried shuffling the code around to see if the order of JIT compilation or the “warmup” phase made any difference, but they didn’t.

To be honest, I’m not sure where the kernel time is coming from in the second case – I thought the .NET GC was running in user mode. Anyway, I’ve cross-checked both test cases with the regular System.DateTime facility, and the sum of kernel + user mode is correct in each case.

You can download the C# 2.0 program here:
http://www.kynosarges.de/misc/throw_net.cs

I’ve compiled the program with csc /o throw_net.cs, meaning it runs in native 64-bit mode on my Vista 64 system.

And now I’ll have to go and rip out any and all exceptions I used to control program flow in my C# code, thinking they couldn’t be THAT slow. :frowning:

Kernel mode time could be because of memory allocation? Or some serializing instruction? Hard to tell without digging into it with a debugger. I should pick up on dotNET stuff.

Please don’t run amok and think exceptions are superbad and should be avoided just because of this, the trick is to use them for exceptional conditions, and not to abuse them for general control flow manipulation (and obviously not for tight loops ;)).

If exceptions are used as they ought to be, imho the speed hit could be even worse, and it would still be insignificant.

Chris Nahr: I tested both doing a “throw 42;” and throwing a “class EmptyException {};” - I also tested catching both with the catch-all ellipsis as well as cathing EmptyException specifically. All ways, VS2008 uses kernel32.RaiseException, which always does userkernel transition. I suppose this might have to do with VC++ supporting both SEH and C++ exception, so they probably decided to model C++ exceptions on SEH for simpler codepath?

There’s no reason that C++ exceptions need to go through kernel transitions generally, though. I’m going to have a look at GCC from MingW, I would think they handle everything on their own with usermode code.

Just checked MingW/GCC-3.4.5, which indeed doesn’t end up in userkernel transitions. Throwing 50 million dummy exceptions took roughly 1/4th the time with G++ generated code than with VC++ from VS2008. Please don’t be too quick to infer anything from this though, as we’re talking basically “throw Dummy(); catch(const Dummy);” with no complex stack unwinding etc.

I can’t read memory without making an API call?

I believe the CPU/Memory System takes care of this by creating an
interrupt to ask the OS where the memory is actually mapped.

That’s got to slow things down.

Thanks for the test report, that’s very interesting. Did you try compiling the VC++ executable in debug vs release mode, just in case this makes a difference?

I’m really surprised by these results. Sure, kernel mode transitions don’t necessarily imply terrible performance losses in real-life scenarios, but this seems like such an unnecessary thing to do.

Why did Microsoft choose this architecture for all their languages? Just because it was the simplest thing to do, or to facilitate interfacing with debuggers, or…?