unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any
clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP

By any chance do you have global scope class instance variables? These will
have CTOR/DTORs and might be causing module ?global? exit code to be
generated.

You cannot have any class instances that are not either automatic (stack
allocated) or heap allocated.

Good Luck,

Dave Cattley

Consulting Engineer

Systems Software Development

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Tuesday, December 02, 2008 10:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any
clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP

— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Well, the linker disagrees with you, and it gets to be correct.

There are a few things that will do this - most notably the presence of any global objects - but
before we get in to this, whose C++ kernel package are you using? If the answer is Mark’s, then you
shouldn’t be getting this error. If the answer is ‘none,’ then we need to talk about that. If the
answer is ‘none of the above,’ then I don’t know what to tell you.

Also, try adding ‘-VERBOSE:LIB’ to your sources file and post the output. I don’t know how to do
this using BUILD, but it seems like ‘LINKER_FLAGS’ would work, though it might replace all the
defaults. If so, LINKER_FLAGS=$(LINKER_FLAGS) might work, but not necessarily,
depending on how BUILD expands it.

Although I use C++ in the kernel, given the problems that you’re having, I would really consider
whether you want to do this or not.

Good luck,

mm

A P wrote:
> hello folks,
>
> i am geting this weird linker error when i try building the driver. any
> clues?
>
>
> the driver has c++ classes in it, but no dynamic allocation/dealloc.
>
>
> thanks
>
> AP

m,

this post really tells me how less i know of kernel code writing and tools.

but before we get in to this, whose C++ kernel package are you using? If
the answer is Mark’s, then you shouldn’t be getting this error.

Can you plesae elaborate?

If the answer is ‘none,’ then we need to talk about that. If the answer
is ‘none of the above,’ then I don’t know what to tell you.

so please tell me, as it seems I really don’t know much of this.

thanks

AP

On Tue, Dec 2, 2008 at 7:25 PM, Martin O’Brien wrote:

> Well, the linker disagrees with you, and it gets to be correct.
>
> There are a few things that will do this - most notably the presence of any
> global objects - but before we get in to this, whose C++ kernel package are
> you using? If the answer is Mark’s, then you shouldn’t be getting this
> error. If the answer is ‘none,’ then we need to talk about that. If the
> answer is ‘none of the above,’ then I don’t know what to tell you.
>
> Also, try adding ‘-VERBOSE:LIB’ to your sources file and post the output.
> I don’t know how to do this using BUILD, but it seems like ‘LINKER_FLAGS’
> would work, though it might replace all the defaults. If so,
> LINKER_FLAGS=$(LINKER_FLAGS) might work, but not necessarily,
> depending on how BUILD expands it.
>
> Although I use C++ in the kernel, given the problems that you’re having, I
> would really consider whether you want to do this or not.
>
> Good luck,
>
> mm
>
>
> A P wrote:
>
>> hello folks,
>> i am geting this weird linker error when i try building the driver. any
>> clues?
>> the driver has c++ classes in it, but no dynamic allocation/dealloc.
>> thanks
>> AP
>>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

_atexit is a user-mode library call. Look it up in the MSDN (atexit). This
is used to create user-library exit calls in the C runtime library. So you
are probably misusing C++ in some fashion to cause it to call a CRT
user-level library call.
joe


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Tuesday, December 02, 2008 10:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any
clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP
— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.

joe,

So you are probably misusing C++ in some fashion to cause it to call a CRT
user-level library call

can you give me examples of such cases, would make me understand better.

thanks

AP

On Tue, Dec 2, 2008 at 8:28 PM, Joseph M. Newcomer wrote:

> _atexit is a user-mode library call. Look it up in the MSDN (atexit). This
> is used to create user-library exit calls in the C runtime library. So
> you are probably misusing C++ in some fashion to cause it to call a CRT
> user-level library call.
>
>
> joe
> ------------------------------
>
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] On* Behalf Of *A P
> Sent: Tuesday, December 02, 2008 10:06 PM
> To: Windows System Software Devs Interest List
> Subject: [ntdev] unresolved external symbol _atexit
>
>
>
> hello folks,
>
>
>
> i am geting this weird linker error when i try building the driver. any
> clues?
>
>
>
>
>
> the driver has c++ classes in it, but no dynamic allocation/dealloc.
>
>
>
>
>
> thanks
>
>
>
> AP
>
> — NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
> other seminars visit: http://www.osr.com/seminars To unsubscribe, visit
> the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
> –
> This message has been scanned for viruses and
> dangerous content by MailScanner http:</http:>, and is
> believed to be clean.
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

AP:

We’ve all been where you are right now - at the beginning, staring at a killer learning curve.
Unfortunately, assuming competency in C and a little bit of OS theory background, the tools
represent by far the steepest and longest part of the curve, in my opinion. WinDbg alone, between
the terrible documentation and huge amount of functionality, takes several months to get up to
speed. I would say that’s about how long it took me to get to the point that using it wasn’t an
irritation due to having to look everything up, and I had been a SoftICE user for several years, so
kd in and of itself wasn’t new to me.

In any case, while I feel your pain, assuming that this thread is part of the same project (SMM) as
your other ones, frankly, you’re doing pretty much everything you can to make it worse; assuming
that you have any sort of deadline involving a deliverable, in my opinion, you need to stop and
rethink this whole undertaking before this goes from steep to sheer.

There’s a good chance that you’ve been handed this project by a manager who will not accept any
variation of ‘we won’t meet the deadline,’ but even if this is the case, you would be better of, in
my opinion, trying to make your feelings a matter of record (written). They may fire you on the
spot, but they do, that was going to go down either way.

If this thread is not part of the SMM one(s), then the situation is much better, but I would offer
you the same advice - stop and rethink whether you really need C++ support in the kernel, because it
not only immediately takes you in to (totally) undocumented (as well as complicated) territory, it
also (in my opinion) will limit you to a small handful of people on this list who MIGHT be willing
to get this up and running (C++ RT); for me personally, while on the one I would like to help you,
and use C++ in the kernel myself, on the other, the unless you have a client who is insisting on
this, there’s just no reason to do this, so it makes the significant investment of time on an
ongoing basis that providing that help will require seem less attractive and pointless.

So, here’s what I would do (about the C++ RT problem), as well as a rough outline of the basics;
after that, if you proceed except under the circumstance that you have no choice (client, manager),
you will find me unwilling to offer further help, because I really won’t be helping you, but rather
leading you further from getting something up and running; if someone just handed you a hard
requirement for C++, as long as you tell them that this is not a good idea and they still don’t
care, I’ll do the best I can to help you out.

  1. If you want to use C++ in the kernel, read this page and download and install Mark Roddy’s
    support library:

http://www.hollistech.com/Resources/Cpp/kernel_c_runtime_library.htm

Let’s start with that and hopefully you won’t need the gory details of the implementation of support
in the CRT, kernel and compiler.

A P wrote:

m,

this post really tells me how less i know of kernel code writing and tools.
>but before we get in to this, whose C++ kernel package are you using?
If the answer is Mark’s, then you shouldn’t be getting this error.

Can you plesae elaborate?

> If the answer is ‘none,’ then we need to talk about that. If the
answer is ‘none of the above,’ then I don’t know what to tell you.

so please tell me, as it seems I really don’t know much of this.

thanks

AP

On Tue, Dec 2, 2008 at 7:25 PM, Martin O’Brien
> wrote:
>
> Well, the linker disagrees with you, and it gets to be correct.
>
> There are a few things that will do this - most notably the presence
> of any global objects - but before we get in to this, whose C++
> kernel package are you using? If the answer is Mark’s, then you
> shouldn’t be getting this error. If the answer is ‘none,’ then we
> need to talk about that. If the answer is ‘none of the above,’ then
> I don’t know what to tell you.
>
> Also, try adding ‘-VERBOSE:LIB’ to your sources file and post the
> output. I don’t know how to do this using BUILD, but it seems like
> ‘LINKER_FLAGS’ would work, though it might replace all the defaults.
> If so, LINKER_FLAGS=$(LINKER_FLAGS) might work, but not
> necessarily, depending on how BUILD expands it.
>
> Although I use C++ in the kernel, given the problems that you’re
> having, I would really consider whether you want to do this or not.
>
> Good luck,
>
> mm
>
>
> A P wrote:
>
> hello folks,
> i am geting this weird linker error when i try building the
> driver. any clues?
> the driver has c++ classes in it, but no dynamic
> allocation/dealloc.
> thanks
> AP
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
>

Why try to understand this via posts every 10 to 15 minutes? These posts will probably stop until morning since it is getting late on the West Coast of the USA. There is a document at microsoft.com about why you shouldn’t use C++ in the kernel. Yes, there are a lot of companies that use C++ in the kernel, but most of them don’t post questions at this elementary level.

In the sources file add on a line by itself: “MSC_WARNING_LEVEL=/WX /W4 /Fa$(o)\ /FAcs”

After you build -ceZ your driver look in the object directory for files with the extension of .cod. Use a text search for atexit on all of those files. When you find it you can probably determine what causes your driver to call it. If it is called by library add the options to show what is linked from what module when you link. MSDN Library has the information on the linker options. I saw another post about adding options to the linker from Martin and it is correct. I usually use “/MAP /MAPINFO:EXPORTS” on mine.

My recommendation is to stay away from C++ in the kernel. I have used it many times in the past and it can be useful, but unlike the authors of KMDF I don’t have the ability to get the compiler changed to emit functions only where they won’t hurt. I have found that almost all authors of drivers using C++ do not allow any pagable code in their driver since automatically generated functions can be added to the paged code but called from non-paged code. This is one of the big problems but not the only one. Read that document and you can find a link to it by searching the two driver newsgroups.

“A P” wrote in message news:xxxxx@ntdev…
joe,

>So you are probably misusing C++ in some fashion to cause it to call a CRT user-level library call

can you give me examples of such cases, would make me understand better.

thanks

AP

On Tue, Dec 2, 2008 at 8:28 PM, Joseph M. Newcomer wrote:

_atexit is a user-mode library call. Look it up in the MSDN (atexit). This is used to create user-library exit calls in the C runtime library. So you are probably misusing C++ in some fashion to cause it to call a CRT user-level library call.

joe

----------------------------------------------------------------------------

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of A P

Sent: Tuesday, December 02, 2008 10:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP

— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.



NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

We (the KMDF team) did not have the power to change the compiler, we worked within the same confines that the driver writing community must deal with. While we do have global structures in KMDF , they are just that, structures (w/out constructors or destructors). We manually initialize and destruct them at the appropriate time when the runtime loads and unloads.

d

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of David Craig
Sent: Tuesday, December 02, 2008 9:43 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] unresolved external symbol _atexit

Why try to understand this via posts every 10 to 15 minutes? These posts will probably stop until morning since it is getting late on the West Coast of the USA. There is a document at microsoft.com about why you shouldn’t use C++ in the kernel. Yes, there are a lot of companies that use C++ in the kernel, but most of them don’t post questions at this elementary level.

In the sources file add on a line by itself: “MSC_WARNING_LEVEL=/WX /W4 /Fa$(o)\ /FAcs”

After you build -ceZ your driver look in the object directory for files with the extension of .cod. Use a text search for atexit on all of those files. When you find it you can probably determine what causes your driver to call it. If it is called by library add the options to show what is linked from what module when you link. MSDN Library has the information on the linker options. I saw another post about adding options to the linker from Martin and it is correct. I usually use “/MAP /MAPINFO:EXPORTS” on mine.

My recommendation is to stay away from C++ in the kernel. I have used it many times in the past and it can be useful, but unlike the authors of KMDF I don’t have the ability to get the compiler changed to emit functions only where they won’t hurt. I have found that almost all authors of drivers using C++ do not allow any pagable code in their driver since automatically generated functions can be added to the paged code but called from non-paged code. This is one of the big problems but not the only one. Read that document and you can find a link to it by searching the two driver newsgroups.

“A P” > wrote in message news:xxxxx@ntdev…
joe,

>So you are probably misusing C++ in some fashion to cause it to call a CRT user-level library call

can you give me examples of such cases, would make me understand better.

thanks

AP

On Tue, Dec 2, 2008 at 8:28 PM, Joseph M. Newcomer > wrote:

_atexit is a user-mode library call. Look it up in the MSDN (atexit). This is used to create user-library exit calls in the C runtime library. So you are probably misusing C++ in some fashion to cause it to call a CRT user-level library call.

joe

________________________________

From: xxxxx@lists.osr.commailto:xxxxx [mailto:xxxxx@lists.osr.commailto:xxxxx] On Behalf Of A P

Sent: Tuesday, December 02, 2008 10:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP

— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by MailScannerhttp:</http:>, and is
believed to be clean.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

> If this thread is not part of the SMM one(s), then the situation is much better, but I would offer

you the same advice - stop and rethink whether you really need C++ support in the kernel

Correct. You can code all OOP design patterns (like visitors) in C. And yes, if the code is well architected, it is well-readable in C so as in C++.

All OOP features are available in C, though with some trivial effort like maintaining the method tables manually.

As about the metaprogramming/ADT C++ features - templates, operator+ and so on - then I consider them to be much more evil then good, they are only good in very limited cases and have major potential of producing uncomprehendable code. Some other features like RTTI are just plain evil, since they break the OO paradigm.

Also, with RTTI and dynamic_cast, it looks like for me that you rely on compiler-hardcoded stuff too much. I would better implement my own RTTI in a way similar to DECLARE_DYNAMIC in old MFC (it’s trivial), and dynamic_cast in a way similar to COM ->QueryInterface. This will give me flexibility. And - once more - these features are usable only in 1% of all C++ code. That’s why I only use C-style casts in C++, and consider the xxx_cast to be evil.

C++ exceptions give no value in the kernel (unless you will wrap each kernel object and each lock acquisition to the object with destructor). The thing is that the restart context is known for them only if all resources are allocated by C++ object creation, and object must have a destructor. If you have some loopholes in this paradigm - then you will have resource (and lock acquisition) leaks on an exception, and, in general, will be unable to continue properly after the exception will be caught.

Proper and really reliable use of this mechanism requires ~the same amount of effort as just replacing it with return NTSTATUS value checks.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

>Why try to understand this via posts every 10 to 15 minutes? These posts will probably stop until

morning since it is getting late on the West Coast of the USA.

There is also East Coast of the USA, UK, Europe, India, Russia/Ukraine and Asian-Pacific region. Combined, they provide more list participants then the West Coast.

After you build -ceZ your driver look in the object directory for files with the extension of .cod. Use a
text search for atexit on all of those files.

I would expect _atexit is called by some internal C++ compiler-generated code which implements constructors and destructors of the global objects.

In this particular case, probably it is a good idea to _implement atexit in the kernel and call this implementation from the Unload routine.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

I’ve never used C++ in the kernel. So I’m not sure under what conditions it
would call atexit; it sounds like it is setting up for global destructors,
but this is just kernel-incompatible C++ magic. If it happens, you’ve done
something wrong. Probably used C++.

joe


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Tuesday, December 02, 2008 11:48 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] unresolved external symbol _atexit

joe,

So you are probably misusing C++ in some fashion to cause it to call a CRT
user-level library call

can you give me examples of such cases, would make me understand better.

thanks

AP

On Tue, Dec 2, 2008 at 8:28 PM, Joseph M. Newcomer
wrote:
_atexit is a user-mode library call. Look it up in the MSDN (atexit). This
is used to create user-library exit calls in the C runtime library. So you
are probably misusing C++ in some fashion to cause it to call a CRT
user-level library call.
joe
_____

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of A P

Sent: Tuesday, December 02, 2008 10:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any
clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP
— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.

Almost certainly (as I know has been pointed out) because you have a global instance of a class defined:

Class foo
{
Stuff…
}

Then anywhere outside a function:

Foo bar;

It is possible to construct a solution to this [I did a decade or so ago, and I’ve seen at least one other since in my consultant days], but you really have to understand the compiler and linker to do it. It’s much easier to do this:

Foo* bar;

extern “C” NTSTATUS DriverEntry(more stuff)
{
Bar = new Foo;
[Then even more stuff, of course].
}

Feel free to email me privately if you have questions about using C++ in the kernel. Been doing it for years and I enjoy p***ing off the dinosaurs.

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Tuesday, December 02, 2008 7:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP
— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

It is also used for implicitly generated code for global constructors and destructors as previously mentioned.

Check for global instances of class objects.

? S


From: Joseph M. Newcomer
Sent: Tuesday, December 02, 2008 22:29
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] unresolved external symbol _atexit

_atexit is a user-mode library call. Look it up in the MSDN (atexit). This is used to create user-library exit calls in the C runtime library. So you are probably misusing C++ in some fashion to cause it to call a CRT user-level library call.
joe
________________________________
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Tuesday, December 02, 2008 10:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP
— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by MailScannerhttp:</http:>, and is
believed to be clean.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Which raises the issue: why are there global objects in a driver? This is
extremely risky (in general, most people who declare global objects are C
application programmers who are not aware of the numerous problems this
creates in a driver-and for that matter, they shouldn’t have been global
objects anyway, even in C, but most people are prone to using them). Every
driver that I have ever reviewed that had a global declaration (other than
the write-once pseudo-const of saving the DriverEntry path value) got it
wrong. (The next step down is declaring local static values in functions.a
really dangerous practice much beloved by C programmers)
joe


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Skywing
Sent: Wednesday, December 03, 2008 12:35 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] unresolved external symbol _atexit

It is also used for implicitly generated code for global constructors and
destructors as previously mentioned.

Check for global instances of class objects.

  • S

From: Joseph M. Newcomer
Sent: Tuesday, December 02, 2008 22:29
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] unresolved external symbol _atexit
_atexit is a user-mode library call. Look it up in the MSDN (atexit). This
is used to create user-library exit calls in the C runtime library. So you
are probably misusing C++ in some fashion to cause it to call a CRT
user-level library call.
joe
_____

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Tuesday, December 02, 2008 10:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any
clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP
— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.

There are justifications for using globals, but generally you are correct in that they are misused. If you have a crash dump callback for secondary data and your driver supports multiple instances of your hardware, using a global is the only way to find all your device structures. Since you are running at HIGH_LEVEL in the callback, you only need to see if the global linked list was in the process of being updated and if not you can grab the information you need to add to the dump. Some of the WMI performance information might be driver oriented vice device specific, so that can be another justification.

Please be specific as to the problems you think local static values can cause. I see some use for them, but don’t think I have done it in a driver recently. I do see a place where a table is needed and it should not be exposed via a global. That table is initialized at compile time and not modified during execution, so I think it is acceptable. It is an easy way to do a type of data & code binding as is done in C++, but in standard C. It could be done with a global, but it shows its usage and restricts its access easily.

“Joseph M. Newcomer” wrote in message news:xxxxx@ntdev…
Which raises the issue: why are there global objects in a driver? This is extremely risky (in general, most people who declare global objects are C application programmers who are not aware of the numerous problems this creates in a driver-and for that matter, they shouldn’t have been global objects anyway, even in C, but most people are prone to using them). Every driver that I have ever reviewed that had a global declaration (other than the write-once pseudo-const of saving the DriverEntry path value) got it wrong. (The next step down is declaring local static values in functions.a really dangerous practice much beloved by C programmers)

joe

------------------------------------------------------------------------------

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Skywing
Sent: Wednesday, December 03, 2008 12:35 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] unresolved external symbol _atexit

It is also used for implicitly generated code for global constructors and destructors as previously mentioned.

Check for global instances of class objects.

- S

------------------------------------------------------------------------------

From: Joseph M. Newcomer
Sent: Tuesday, December 02, 2008 22:29
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] unresolved external symbol _atexit

_atexit is a user-mode library call. Look it up in the MSDN (atexit). This is used to create user-library exit calls in the C runtime library. So you are probably misusing C++ in some fashion to cause it to call a CRT user-level library call.

joe

------------------------------------------------------------------------------

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Tuesday, December 02, 2008 10:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP

— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer


This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

See below.


From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of David Craig
Sent: Wednesday, December 03, 2008 2:41 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] unresolved external symbol _atexit

There are justifications for using globals, but generally you are correct in
that they are misused. If you have a crash dump callback for secondary data
and your driver supports multiple instances of your hardware, using a global
is the only way to find all your device structures.
****
Wouldn’t this be doable simply by finding the DRIVER_OBJECT and walking its
list.?
****

Since you are running at HIGH_LEVEL in the callback, you only need to see if
the global linked list was in the process of being updated and if not you
can grab the information you need to add to the dump. Some of the WMI
performance information might be driver oriented vice device specific, so
that can be another justification.

****
Yes, the driver-level stuff is one of the justifications. Unfortunately,
the drivers I’ve seen aren’t at all that sophisticated, they just declare
global variables “So I don’t have to keep passing parameters down the stack,
because that’s expensive!” ARGH!

Most of the crashes are from concurrent access to these variables. The
usual: “We plugged a second device in, and every time we do this it
bluescreens”. I’m sure you’ve all seen these. Reading these drivers is
about as much fun as chewing on lemons for several hours.

I had once case where they said “The system would just hang, and someone
told us we were getting deadlock, so we started removing spin locks until it
stopped deadlocking”.
****

Please be specific as to the problems you think local static values can
cause. I see some use for them, but don’t think I have done it in a driver
recently. I do see a place where a table is needed and it should not be
exposed via a global. That table is initialized at compile time and not
modified during execution, so I think it is acceptable. It is an easy way
to do a type of data & code binding as is done in C++, but in standard C.
It could be done with a global, but it shows its usage and restricts its
access easily.
****
The usual one is “retaining state for the next call”. In a preemptive,
multiprocessor, preemptive threading environment, with the possibility of
multiple instances of the device, this is extremely dangerous; these are all
old C application programmers to whom the concepts of “threads” and
“concurrency” are a foreign language. When I explain race conditions to
them, they assure me that these are not possible because.and go off on some
single-threaded explanation that cannot possibly work. What I tell my
students is “If you have a global variable or local static variable that is
not preceded by the word ‘const’, consider that you have probably made a
coding error. When you get sophisticated enough that you know what you are
doing, you will realize that there are two exceptions: write-once constants
and true global state” In our book on device drivers, we actually chose a
DDK example driver for discussion that uses genuine global state, among
other reasons so we could talk about the need for and proper management of
global state, but in general, drives with global state and static local
variables represent the first or second driver the coder has written, and
they are still thinking single-threaded application-level code.

So when I see a global variable, the first thing I do is see how it is being
(mis)used, and I’m almost always right about the (mis) part.

Of course, they way they solve this is to correct it by stuffing it into the
device extension, without actually solving the fundamental race conditions
that can occur. About half the time, they win by accident, because once it
is no longer shared across all device instances, there is not a problem.
But sometimes it is passive/dpc/isr level concurrency that nails them.
Either the algorithm is fundamentally wrong, or there is no synchronization.

The problem is that they don’t have a good “ownership” model of the data
(e.g., the buffer pointer in the extension is either “owned” by the dequeue
handler, or the ISR, or the DPC, sequentially and never concurrently, and it
will work. Or there is an overlap, and I still get “but a++ is an atomic
operation, so cannot fail!” (How they determined this is unknown, since I
rarely see the compiler generating an INC instruction.but it was once true
on a couple machines in the past [PDP-11 and Vax] so someone probably passed
this on as “urban legend”).

There’s nothing wrong with const and pseudo-const (write once at
initialization and never change) data, but that’s not where I see the
problems.

joe

“Joseph M. Newcomer” wrote in message
news:xxxxx@ntdev…
Which raises the issue: why are there global objects in a driver? This is
extremely risky (in general, most people who declare global objects are C
application programmers who are not aware of the numerous problems this
creates in a driver-and for that matter, they shouldn’t have been global
objects anyway, even in C, but most people are prone to using them). Every
driver that I have ever reviewed that had a global declaration (other than
the write-once pseudo-const of saving the DriverEntry path value) got it
wrong. (The next step down is declaring local static values in functions.a
really dangerous practice much beloved by C programmers)
joe

_

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Skywing
Sent: Wednesday, December 03, 2008 12:35 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] unresolved external symbol atexit

It is also used for implicitly generated code for global constructors and
destructors as previously mentioned.

Check for global instances of class objects.

- S



From: Joseph M. Newcomer
Sent: Tuesday, December 02, 2008 22:29
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] unresolved external symbol _atexit
_atexit is a user-mode library call. Look it up in the MSDN (atexit). This
is used to create user-library exit calls in the C runtime library. So you
are probably misusing C++ in some fashion to cause it to call a CRT
user-level library call.
joe

_____

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Tuesday, December 02, 2008 10:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any
clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP
— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging and
other seminars visit: http://www.osr.com/seminars To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

This message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


This message has been scanned for viruses and
dangerous content by http:</http:> MailScanner, and is
believed to be clean.

Probably a global C++ object. The init code for this object will never
be called because there is no CRT. That code registers a destructor as
I recall using _atexit(). So, you have two problems really. Make sure
you don’t have global objects with constructors, ie most C++ objects.
Note that this problem can be solved, but it requires some work and
discipline so it is a topic for a later time.

If that isn’t it, add the compiler switch to generate asm output mixed
with source and recompile. Search the .asm file(s) for the _atexit()
call and you can work out what is going on. As someone else pointed
out, turning on verbose linker output will tell you roughly where the
call resides, but not precisely.

NT Insider, Vol 14, Issue 2, March - April 2007 has a guest article by
Edouard Alligand about using C++ in an NT Driver. It is generally
correct. It is on the OSR online site if you don’t have that particular
issue. Read it. It is critical that you understand what aspects of C++
you can use and what aspects you must not use.

A P wrote:

hello folks,

i am geting this weird linker error when i try building the driver.
any clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP
— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging
and other seminars visit: http://www.osr.com/seminars To unsubscribe,
visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

It could also be a static C++ object - i.e.

Class Foo { /* assume this has a destructor */ };
Class Bar {
Static class Foo x;
}

Of course this is just a global that’s not in the global namespace … but they’re also worth looking for.

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Mark Spiegel
Sent: Wednesday, December 03, 2008 1:33 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] unresolved external symbol _atexit

Probably a global C++ object. The init code for this object will never
be called because there is no CRT. That code registers a destructor as
I recall using _atexit(). So, you have two problems really. Make sure
you don’t have global objects with constructors, ie most C++ objects.
Note that this problem can be solved, but it requires some work and
discipline so it is a topic for a later time.

If that isn’t it, add the compiler switch to generate asm output mixed
with source and recompile. Search the .asm file(s) for the _atexit()
call and you can work out what is going on. As someone else pointed
out, turning on verbose linker output will tell you roughly where the
call resides, but not precisely.

NT Insider, Vol 14, Issue 2, March - April 2007 has a guest article by
Edouard Alligand about using C++ in an NT Driver. It is generally
correct. It is on the OSR online site if you don’t have that particular
issue. Read it. It is critical that you understand what aspects of C++
you can use and what aspects you must not use.

A P wrote:

hello folks,

i am geting this weird linker error when i try building the driver.
any clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP
— NTDEV is sponsored by OSR For our schedule of WDF, WDM, debugging
and other seminars visit: http://www.osr.com/seminars To unsubscribe,
visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

The driver object has been taken over by NDIS. It no longer belongs to us. Device object creation is done in the port driver and not in the miniports. Yes, it could be workable in a ‘normal’ driver. In the NDIS world, we don’t own the driver object and it is passed to the NDIS registration call. That is the only time we touch it. None of the normal setting up of function pointers occurs. I realize you know this, but someone reading might be misled. I think much of this occurs with KMDF also which is why there is a special way to register with KMDF that keeps it from trying to own the driver object. A sample NDIS driver is supposed to show how this is done so you have an upper NDIS edge, but a lower KMDF edge. I have not looked at that sample since we only have our hardware below us and no other driver is called, but it is useful for a USB network adapter.

I do agree with what you say about some that think passing parameters down the stack is expensive. The solution is to keep the parameters in the device extension where everyone can have access to them. Those that are unique to a specific request then can be packaged into one structure to reduce the amount of data being pushed on the stack. I think the prefast default stack limit test of 1KB is a little excessive for many drivers. I like to keep a single function’s stack usage to below 256 bytes and even that is a little high for legacy file system filters where reentrancy is a possibility due to other filters. That is a big advantage to the minifilter model.

However, if this world of device drivers were easy, it wouldn’t be as much fun or pay as much. Even with miniports, minifilters, and KMDF it is still far more difficult than writing C# for small user programs. The interactions between other drivers both OS and third party, can keep you learning and thinking.

“Joseph M. Newcomer” wrote in message news:xxxxx@ntdev…
See below.

------------------------------------------------------------------------------

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of David Craig
Sent: Wednesday, December 03, 2008 2:41 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] unresolved external symbol _atexit

There are justifications for using globals, but generally you are correct in that they are misused. If you have a crash dump callback for secondary data and your driver supports multiple instances of your hardware, using a global is the only way to find all your device structures.



Wouldn’t this be doable simply by finding the DRIVER_OBJECT and walking its list.?



Since you are running at HIGH_LEVEL in the callback, you only need to see if the global linked list was in the process of being updated and if not you can grab the information you need to add to the dump. Some of the WMI performance information might be driver oriented vice device specific, so that can be another justification.



Yes, the driver-level stuff is one of the justifications. Unfortunately, the drivers I’ve seen aren’t at all that sophisticated, they just declare global variables “So I don’t have to keep passing parameters down the stack, because that’s expensive!” ARGH!

Most of the crashes are from concurrent access to these variables. The usual: “We plugged a second device in, and every time we do this it bluescreens”. I’m sure you’ve all seen these. Reading these drivers is about as much fun as chewing on lemons for several hours.

I had once case where they said “The system would just hang, and someone told us we were getting deadlock, so we started removing spin locks until it stopped deadlocking”.



Please be specific as to the problems you think local static values can cause. I see some use for them, but don’t think I have done it in a driver recently. I do see a place where a table is needed and it should not be exposed via a global. That table is initialized at compile time and not modified during execution, so I think it is acceptable. It is an easy way to do a type of data & code binding as is done in C++, but in standard C. It could be done with a global, but it shows its usage and restricts its access easily.

****

The usual one is “retaining state for the next call”. In a preemptive, multiprocessor, preemptive threading environment, with the possibility of multiple instances of the device, this is extremely dangerous; these are all old C application programmers to whom the concepts of “threads” and “concurrency” are a foreign language. When I explain race conditions to them, they assure me that these are not possible because.and go off on some single-threaded explanation that cannot possibly work. What I tell my students is “If you have a global variable or local static variable that is not preceded by the word ‘const’, consider that you have probably made a coding error. When you get sophisticated enough that you know what you are doing, you will realize that there are two exceptions: write-once constants and true global state” In our book on device drivers, we actually chose a DDK example driver for discussion that uses genuine global state, among other reasons so we could talk about the need for and proper management of global state, but in general, drives with global state and static local variables represent the first or second driver the coder has written, and they are still thinking single-threaded application-level code.

So when I see a global variable, the first thing I do is see how it is being (mis)used, and I’m almost always right about the (mis) part.

Of course, they way they solve this is to correct it by stuffing it into the device extension, without actually solving the fundamental race conditions that can occur. About half the time, they win by accident, because once it is no longer shared across all device instances, there is not a problem. But sometimes it is passive/dpc/isr level concurrency that nails them. Either the algorithm is fundamentally wrong, or there is no synchronization.

The problem is that they don’t have a good “ownership” model of the data (e.g., the buffer pointer in the extension is either “owned” by the dequeue handler, or the ISR, or the DPC, sequentially and never concurrently, and it will work. Or there is an overlap, and I still get “but a++ is an atomic operation, so cannot fail!” (How they determined this is unknown, since I rarely see the compiler generating an INC instruction.but it was once true on a couple machines in the past [PDP-11 and Vax] so someone probably passed this on as “urban legend”).

There’s nothing wrong with const and pseudo-const (write once at initialization and never change) data, but that’s not where I see the problems.

joe

“Joseph M. Newcomer” wrote in message news:xxxxx@ntdev…

Which raises the issue: why are there global objects in a driver? This is extremely risky (in general, most people who declare global objects are C application programmers who are not aware of the numerous problems this creates in a driver-and for that matter, they shouldn’t have been global objects anyway, even in C, but most people are prone to using them). Every driver that I have ever reviewed that had a global declaration (other than the write-once pseudo-const of saving the DriverEntry path value) got it wrong. (The next step down is declaring local static values in functions.a really dangerous practice much beloved by C programmers)

joe

----------------------------------------------------------------------------

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Skywing
Sent: Wednesday, December 03, 2008 12:35 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] unresolved external symbol _atexit

It is also used for implicitly generated code for global constructors and destructors as previously mentioned.

Check for global instances of class objects.

- S

----------------------------------------------------------------------------

From: Joseph M. Newcomer
Sent: Tuesday, December 02, 2008 22:29
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] unresolved external symbol _atexit

_atexit is a user-mode library call. Look it up in the MSDN (atexit). This is used to create user-library exit calls in the C runtime library. So you are probably misusing C++ in some fashion to cause it to call a CRT user-level library call.

joe

----------------------------------------------------------------------------

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of A P
Sent: Tuesday, December 02, 2008 10:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] unresolved external symbol _atexit

hello folks,

i am geting this weird linker error when i try building the driver. any clues?

the driver has c++ classes in it, but no dynamic allocation/dealloc.

thanks

AP