Discussion:
c++ in windows kernel mode
(too old to reply)
y***@gmail.com
2007-07-31 16:19:05 UTC
Permalink
{ As far as possible, please try to confine this discussion to general
system-independent issues. We recognize that at this level some details
cannot be discussed without concrete system-dependent examples. -mod }

here's an interesting article pointing out the fatal pitfalls
of c++ in kernel mode:

http://www.microsoft.com/whdc/driver/kernel/KMcode.mspx

Please criticize or suggest workarounds, if any.
Also,are there options/switches that help these problems mentioned?
have there been improvements in generated code since this article was
written?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Zeljko Vrba
2007-07-31 19:34:53 UTC
Permalink
Post by y***@gmail.com
http://www.microsoft.com/whdc/driver/kernel/KMcode.mspx
Please criticize or suggest workarounds, if any.
The warning of templates seems pointless: it's as if they were saying that
C preprocessor was unsafe in kernel mode. Yes, templates may increase
code size, but beyond that - it's as if you wrote C if you stick only to
C constructs in template code. Ie. templates are as (un)safe as the code
contained within the template.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Mathias Gaunard
2007-07-31 19:42:13 UTC
Permalink
Post by y***@gmail.com
here's an interesting article pointing out the fatal pitfalls
http://www.microsoft.com/whdc/driver/kernel/KMcode.mspx
I don't see any real pitfall here.

Plus I don't see how this article is even remotely interesting. Much
of it is utter garbage. They're basically saying that using C++
features that are not C features is unsafe.

The first issue is that you can't place code and data wherever you
want.
The funny part is that using C doesn't solve any of the "problems"
they're talking about, they still exist.
What "solves" the problems is using the proprietary extensions they
made for C. (nothing really prevents from adapting those to C++, while
it would indeed be quite more complicated)
I'm not even sure those features are needed at all for kernel coding.

A lot of issues that they are mentioning are only related to their
implementation, not to C++ itself.
They're for example mentioning non-issues related to name mangling and
problems from using templates in DLLs, which are implementation
specific.
More ridiculous, they're also saying using C++ is dangerous because
they might decide some day to change their ABI. (which wouldn't be so
much of a bad thing, since theirs isn't that good)
They're also saying their implementations of exceptions and rtti suck
and can't be used in kernel mode. It's quite a shame, since exceptions
would definitely be a plus for kernel coding.

Most of the stuff they talk about is not related to kernel coding but
instead to thread-safety (some kernels don't even need to be thread-
safe actually). Both C and C++ having no notion of what a thread is,
it can't be helped that it doesn't define the behaviour of
multithreaded programs.
Note, however, that the next C++ standard will have multithreading-
related specifications. Some implementations are already good enough
to take care of some issues, and there are tricks to do so portably.
Post by y***@gmail.com
Please criticize or suggest workarounds, if any.
Actually, it's making use of good C++ instead of the usual horrible C
that will improve the quality, efficiency and reliability of your
code.

Sacrificing C++ features just because it causes troubles with their
implementation and platform is no good reason.
However, since you're tied to their implementation and platform, their
platform-specific issues, mostly tied to their runtime, will still be
here whatever you do.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Le Chaud Lapin
2007-08-01 05:19:05 UTC
Permalink
Post by y***@gmail.com
{ As far as possible, please try to confine this discussion to general
system-independent issues. We recognize that at this level some details
cannot be discussed without concrete system-dependent examples. -mod }
here's an interesting article pointing out the fatal pitfalls
http://www.microsoft.com/whdc/driver/kernel/KMcode.mspx
Please criticize or suggest workarounds, if any.
Also,are there options/switches that help these problems mentioned?
have there been improvements in generated code since this article was
written?
I'v experienced 1st-hand what it was like to (try to) write a Kernel
Mode driver in C++, under Windows. It was an NDIS (Network Device
Interface Specification) driver meant to support a new kind of network
protocol stack.

As one can imagine, the environment in which the driver is expected to
run is differen between the two modes, and being somewhat stubborn, I
was determined to see how far one could get away with using C++ in
kernel model.

By far, the biggest slap in the face is memory management. It simply
is not possible to use new/delete willy-nilly as one would in user
mode. One has to remain cognizant of what type of memory should be
used at which point. Of course, anyone embarking upon a driver project
already knows this, so the question is, "How much pain should the
programmer expect from not being able to remain ignorant of memory
management context?" The anser is: A LOT. I fiddled,
faddled...nothing work. My entire user-mode C++ library was
essentially useless. However, if you carefully design the constructor/
destructor pairs of kernel-mode classes to use the special kernel-mode
memory management function, you might get some relief.

Then there are issues with floating point. As pointed out in the
article, one cannot simply write:

float two = 1.0 + 1.0; // Makes kernel very angry.

Though I had no need for them in my driver, I would expect virtual
functions to work.

I would expect templates to pose no problems.

Exception handling was another major headache. As one can imagine,
simply providing a "library" to support exception handling is *not*
sufficient. One has to think about what happens when stack is
completely unwound.

Global static objects were another issue. Have to be careful here and
make sure whatever compiler you are using, does what you expect. You
should also make sure that you do not do any heavy-lifting in
contsructor of a global object. This was true in user-mode in some
cases, but can be fatal in kernel-mode.

In spite of all of this, my kernel-mode files still end in .cpp,
not .c. Why? I like declaring my variables just before the point
where I intend to use them. :)

-Le Chaud Lapin-


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Mathias Gaunard
2007-08-01 20:29:32 UTC
Permalink
Post by Le Chaud Lapin
By far, the biggest slap in the face is memory management.
It simply
is not possible to use new/delete willy-nilly as one would in user
mode.
Using new/delete willy-nilly, even in user mode, is not really a good
thing.
You should stick to RAII, value semantics and allocating objects on
the stack, unless you need to allocate them dynamically.
Then if you still choose to allocate them dynamically, an allocation
strategy such as mark-and-sweep or freelists might be more suited than
simply using the general purpose memory allocator.

There is still, of course, a need for a good general purpose memory
allocator to allocate from your pools.
new/delete are no good, it's not new, but nothing prevents you from
having better and more suited interfaces.
Post by Le Chaud Lapin
One has to remain cognizant of what type of memory should be
used at which point. Of course, anyone embarking upon a driver project
already knows this, so the question is, "How much pain should the
programmer expect from not being able to remain ignorant of memory
management context?"
If you can't manage memory, you shouldn't be using C++ to begin with.
Post by Le Chaud Lapin
Then there are issues with floating point.
As pointed out in the
float two = 1.0 + 1.0; // Makes kernel very angry.
It's probably irrelevant, but in that case any recent compiler should
calculate that at compile-time.
Also, good compilers allow an option to say you do not want to use the
FPU, and that they should therefore use other means to perform
floating point calculations, or that those should be disabled.

Anyway, those issues are in no way C++ specific, and only depend on
the implementation.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Stephen Howe
2007-08-02 00:38:40 UTC
Permalink
Post by Le Chaud Lapin
As one can imagine, the environment in which the driver is expected to
run is differen between the two modes, and being somewhat stubborn, I
was determined to see how far one could get away with using C++ in
kernel model.
By far, the biggest slap in the face is memory management. It simply
is not possible to use new/delete willy-nilly as one would in user
mode. One has to remain cognizant of what type of memory should be
used at which point. Of course, anyone embarking upon a driver project
already knows this, so the question is, "How much pain should the
programmer expect from not being able to remain ignorant of memory
management context?" The anser is: A LOT. I fiddled,
faddled...nothing work. My entire user-mode C++ library was
essentially useless. However, if you carefully design the constructor/
destructor pairs of kernel-mode classes to use the special kernel-mode
memory management function, you might get some relief.
This is what bothers me about Bjarne's original claim that C++ could be used
as a systems language.
Both C++ and to a much lesser degree C compiler vendors use certain internal
functions or OS features to implement the language.
For example, on certain 32-bit CPUs there are no 64-bit multiply or divide
instructions so an internal function has be called.
new/delete is another case.
Implementing exceptions, dynamic_cast is another case.

What happens if some of how this internal machinery works gets in the way
for writing some system drivers?
It seems to me that programmers have to have an awareness of how the vendor
has implemented certain language/library features and maybe not use them for
system programming.

It is laudable that C++ and C can be used for systems programming.
But some awareness of vendor choices seems essential - you cant just ignore
this.

Stephen Howe
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Bo Persson
2007-08-02 17:27:55 UTC
Permalink
Stephen Howe wrote:
::: As one can imagine, the environment in which the driver is
::: expected to run is differen between the two modes, and being
::: somewhat stubborn, I was determined to see how far one could get
::: away with using C++ in kernel model.
:::
::: By far, the biggest slap in the face is memory management. It
::: simply is not possible to use new/delete willy-nilly as one would
::: in user mode. One has to remain cognizant of what type of memory
::: should be used at which point. Of course, anyone embarking upon a
::: driver project already knows this, so the question is, "How much
::: pain should the programmer expect from not being able to remain
::: ignorant of memory management context?" The anser is: A LOT. I
::: fiddled, faddled...nothing work. My entire user-mode C++ library
::: was essentially useless. However, if you carefully design the
::: constructor/ destructor pairs of kernel-mode classes to use the
::: special kernel-mode memory management function, you might get
::: some relief.
::
:: This is what bothers me about Bjarne's original claim that C++
:: could be used as a systems language.

Who says it couldn'`t? Here we have the kernel guys assuming
everything works like their C compiler. Is that a C++ problem?

::
:: What happens if some of how this internal machinery works gets in
:: the way for writing some system drivers?
:: It seems to me that programmers have to have an awareness of how
:: the vendor has implemented certain language/library features and
:: maybe not use them for system programming.

Or you could have the kernel guys supply a non-paged allocator. Or you
could specify the loader format so that it recognizes non-pageable
data, like vtables. Is this a compiler problem?

::
:: It is laudable that C++ and C can be used for systems programming.
:: But some awareness of vendor choices seems essential - you cant
:: just ignore this.

So is it the vendor choices that are the problem, or the C++ language?

It is especially "funny" when the OS and the compiler come from the
same vendor. :-)


Bo Persson
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Martin Bonner
2007-08-01 20:22:54 UTC
Permalink
Post by y***@gmail.com
{ As far as possible, please try to confine this discussion to general
system-independent issues. We recognize that at this level some details
cannot be discussed without concrete system-dependent examples. -mod }
here's an interesting article pointing out the fatal pitfalls
http://www.microsoft.com/whdc/driver/kernel/KMcode.mspx
Please criticize or suggest workarounds, if any.
Also,are there options/switches that help these problems mentioned?
have there been improvements in generated code since this article was
written?
I quote from the article:
"These problems are due more to the C++ implementation and the kernel
environment than to the inherent properties of the C++ language."

"The following areas require particular care in kernel-mode drivers.
These apply to both languages (C and C++)"

The additional functionality that a C++ compiler implements
automatically (as compared to a C compiler) does make it more
difficult to control the compiler output. That is a problem in kernel
mode.

There are a number of references to inheritance hierachies causing
problems. I don't see why single inheritance (to arbitrary depth)
should be tricky.

To be really useful for kernel mode, it does look like a published
object model would be useful.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
vijayan
2007-08-01 20:30:58 UTC
Permalink
Post by y***@gmail.com
{ As far as possible, please try to confine this discussion to general
system-independent issues. We recognize that at this level some details
cannot be discussed without concrete system-dependent examples. -mod }
here's an interesting article pointing out the fatal pitfalls
http://www.microsoft.com/whdc/driver/kernel/KMcode.mspx
Please criticize or suggest workarounds, if any.
Also,are there options/switches that help these problems mentioned?
have there been improvements in generated code since this article was
written?
i've used c++ quite often in windows kernel mode code. the c++ library
that ships with the microsoft compiler is a definite no; so are some c+
+ features like exceptions.
however, i have written various overloaded versions of operator new/
delete (which internally call kernel memory management functions). i
have also rewritten equivalent headers for <algorithms>, <functional>,
<vector>, <deque> etc which are quite usable in kernel mode. as
mentioned in an earlier post, it is not a good idea to rely on
accurate dynamic initialization of statics at global scope. and one
has to be aware of thread context/safety and interrupt level needs;
the stack size is severely limited, floating point requires special
handling etc. (but these are all issues in C as well). name decoration
issues (only a few) can be handled quite easily by an extern "C"
__stdcall. and in most cases, i have found that for the headers
mentioned, inlining did not increase code size too much.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
B.C.
2007-08-04 05:00:48 UTC
Permalink
What about trying the comeau c++? http://www.comeaucomputing.com/

It generates C code from C++ code.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Loading...