How to catch the null pointer exception? [duplicate] - c++

This question already has answers here:
Catching access violation exceptions?
(8 answers)
Closed 6 years ago.
try {
int* p = 0;
*p = 1;
} catch (...) {
cout << "null pointer." << endl;
}
I tried to catch the exception like this but it doesn't work,any help?

There's no such thing as "null pointer exception" in C++. The only exceptions you can catch, is the exceptions explicitly thrown by throw expressions (plus, as Pavel noted, some standard C++ exceptions thrown intrinsically by standard operator new, dynamic_cast etc). There are no other exceptions in C++. Dereferencing null pointers, division by zero etc. does not generate exceptions in C++, it produces undefined behavior. If you want exceptions thrown in cases like that it is your own responsibility to manually detect these conditions and do throw explicitly. That's how it works in C++.
Whatever else you seem to be looking for has noting to do with C++ language, but rather a feature of particular implementation. In Visual C++, for example, system/hardware exceptions can be "converted" into C++ exceptions, but there's a price attached to this non-standard functionality, which is not normally worth paying.

You cannot. De-referencing a null-pointer is a system thing.
On Linux, the OS raises signals in your application. Take a look at csignal to see how to handle signals. To "catch" one, you'd hook a function in that will be called in the case of SIGSEGV. Here you could try to print some information before you gracefully terminate the program.
Windows uses structured-exception-handling. You could use the instristics __try/__except, as outlined in the previous link. The way I did it in a certain debug utility I wrote was with the function _set_se_translator (because it closely matches hooks). In Visual Studio, make sure you have SEH enabled. With that function, you can hook in a function to call when the system raises an exception in your application; in your case it would call it with EXCEPTION_ACCESS_VIOLATION. You can then throw an exception and have it propagate back out as if an exception was thrown in the first place.

There is a very easy way to catch any kind of exception (division by zero, access violation, etc.) in Visual Studio using try -> catch (...) blocks.
A minor project tweaking is enough. Just enable the /EHa option in project settings. See Project Properties -> C/C++ -> Code Generation -> Modify the Enable C++ Exceptions to "Yes With SEH Exceptions". That's it!
See details here:
http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx

Dereferencing a null (or pointer that's past-the-end of array, or a random invalid pointer) results in undefined behavior. There's no portable way to "catch" that.

C++ doesn't do pointer checking (although I suppose some implementations could). If you try to write to a null pointer it is most likely going to crash hard. It will not throw an exception. If you want to catch this you need to check the value of the pointer yourself before you try to write to it.

Generally you can't. Even if you could it would be like trying to put a band aid on a submarine that has sprung a leak.
A crippled application can do far more damage than one that has crashed. My advice here would be to let it crash then fix why it crashed. Rinse. Repeat.

As others have said, you can't do this in C++.
If I can make a broader point: even in a language that allows you to catch it, the better action is to not touch null pointers. Catching an error when it's already blown up in your face, then deciding to just move on like it didn't happen, is not a good coding strategy. Things like null pointer dereference, stack overflow, etc., should be seen as catastrophic events and defensively avoided, even if your language allows you to react to it differently.

There is no platform independent way to do this. Under Windows/MSVC++ you can use __try/__except
But I wouldn't recommend doing it anyway. You almost certainly cannot recover correctly from a segmentation fault.

If you wanted to you could just do the pointer checking yourself and throw...
if (p == nullptr) throw std::exception("woot! a nullptr!")
p->foo();
so course this would only be to debug the problem, the nullptr should not occur in the first place :)

Short answer- you can't in a portable or standard way, because bugs like this are potentially corrupting the process itself.
Long answer- you can do more than you might think, and definitely more than the default of the program just crashing. However, you need to keep 3 things in mind:
1) These bugs are MORE severe than exceptions and often cannot present as exceptions to your logic.
2) Your detection and library handling of them WILL be platform-dependent on the back end, even though you can provide a clean abstract interface for public consumption.
3) There will always be some crashes that are so bad you cannot even detect them before the end.
Basically, faults like segfaults or heap corruption are not exceptions because they're corrupting the actual process running the program. Anything you coded into the program is part of the program, including exception handling, so anything beyond logging a nice error message before the process dies is inadvisable in the few cases it isn't impossible. In POSIX, the OS uses a signaling system to report faults like these, and you can register callback functions to log what the error was before you exit. In Windows, the OS can sometimes convert them into normal-looking exceptions which you can catch and recover from.
Ultimately, however, your best bet is to code defensively against such nightmares. On any given OS there will be some that are so bad that you cannot detect them, even in principle, before your process dies. For example, corrupting your own stack pointer is something that can crash you so badly that even your POSIX signal callbacks never see it.

In VC++ 2013 (and also earlier versions) you can put breakpoints on exceptions:
Press Ctrl + Alt + Delete (this will open the exception dialog).
Expand 'Win32 Exceptions'
Ensure that "0xC0000005 Access Violation" exception is checked.
Now debug again, a breakpoint will be hit exactly when the the null dereference happened.

There is no NULL pointer exception exist in c++ but still you want to catch the same then you need to provide your own class implementation for the same.
below is the example for the same.
class Exception {
public:
Exception(const string& msg,int val) : msg_(msg),e(val) {}
~Exception( ) {}
string getMessage( ) const {return(msg_);}
int what(){ return e;}
private:
string msg_;
int e;
};
Now based on NULL pointer check it can be threw like , throw(Exception("NullPointerException",NULL));
and below is the code for catching the same.
catch(Exception& e) {
cout << "Not a valid object: " << e.getMessage( )<< ": ";
cout<<"value="<<e.what()<< endl;
}

Related

Can I use a try catch statement to catch any error instead of being specific?

try{
//some function
}catch(...){
//write information to a file including this line number
}
--
What's stopping me from doing this instead of specifying a null pointer exception for instance? The program is going to crash anyways so I might as well catch all errors if there is something I haven't thought about?
It's a myth that every program fault will be caught by catch(...). In particular the behaviour of a null pointer dereference is undefined so there's no guarantee at all that it would be caught there.
If you want a particularly generic catch site, then catching std::exception& is a good idea, as is const char*.
C++11 gives you the ability to inspect the exception in catch(...) to a degree via std::current_exception. See https://en.cppreference.com/w/cpp/error/current_exception.
In Microsoft C, an extension exists that allows you to try and catch exceptions:
void exceptionTest(void)
{
int *zz = NULL;
__try {
*zz += 1;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
printf("gotcha! 0x%08x\n", GetExceptionCode() );
}
}
From the documentation (MSC2008):
The try-except statement is a Microsoft extension to the C language that enables applications to gain control of a program when events that normally terminate execution occur. Such events are called exceptions, and the mechanism that deals with exceptions is called structured exception handling.
Exceptions can be either hardware- or software-based. Even when applications cannot completely recover from hardware or software exceptions, structured exception handling makes it possible to display error information and trap the internal state of the application to help diagnose the problem. This is especially useful for intermittent problems that cannot be reproduced easily.
Being specific in exception handling facilitates the bug or probleme analysis by a human or programmatically.
You can build an excpetion handling strategy and eventually recover from an exception. Exception is not necessarily a design flaw resulting in some unexpected null pointer. You may throw exception based on data values or process results to stop the processing or take a decision.
You are confusing things. If you dereference a null pointer then there is no automatically created exception. Dereferencing a null pointer is undefined behaviour. Once it happened its too late for exceptions. They simply wont help a bit.
On the other hand if some code checks for null pointer and then throws an exception, then this only makes sense before the null pointer is dereferenced, ie before undefined behaviour can occur. The program will not "crash anyways" when an exception is thrown in such a case (given that someone catches the exception).
Having said this, nobody will stop you from catching all excpetions. It is just that prior to C++11 you had no way to tell what exception was thrown inside a catch(...) block. C++11 has std::current_exception, though I dont know much about it, so I refer you to documentation.

Difference between using try-Catch exception handler and if else condition check? [duplicate]

This question already has answers here:
Is there a general consensus in the C++ community on when exceptions should be used? [closed]
(11 answers)
Closed 9 years ago.
I have used in many places if...else statements, however I'm new to exception handling. What is the main difference among these two?
for eg:
int *ptr = new (nothrow) int[1000];
if (ptr == NULL) {
// Handle error cases here...
}
OR
try
{
int* myarray= new int[1000];
}
catch (exception& e)
{
cout << "Standard exception: " << e.what() << endl;
}
So we are using here standard class for exception which has some in build function like e.what(). So it may be advantage. Other than that all other functionality handling we can do using if...else also. Is there any other merits in using exception handling?
To collect what the comments say in an answer:
since the standardization in 1998, new does not return a null pointer at failure but throws an exception, namely std::bad_alloc. This is different to C's malloc and maybe to some early pre-standard implementations of C++, where new might have returned NULL as well (I don't know, tbh).
There is a possibility in C++, to get a nullpointer on allocation failure instead of an exception as well:
int *ptr = new(std::nothrow) int[1000];
So in short, the first code you have will not work as intended, as it is an attempt of C-style error handling in the presence of C++ exceptions. If allocation fails, the exception will be thrown, the if block will never be entered and the program probably will be terminated since you don't catch the bad_alloc.
There are lots of articles comparing general error handling with exceptions vs return codes, and it would go way to far trying to cover the topic here. Amongst the reasons for exceptions are
Function return types are not occupied by the error handling but can return real values - no "output" function parameters needed.
You do not need to handle the return of every single function call in every single function but can just catch the exception some levels up the call stack where you actually can handle the error
Exceptions can pass arbitraty information to the error handling site, as compared to one global errno variable and a single returned error code.
The main difference is that the version using exception handling at least might work, where the one using the if statement can't possibly work.
Your first snippet:
int *ptr = new int[1000];
if (ptr == NULL) {
// Handle error cases here...
}
...seems to assume that new will return a null pointer in case of failure. While that was true at one time, it hasn't been in a long time. With any reasonably current compiler, the new has only two possibilities: succeed or throw. Therefore, your second version aligns with how C++ is supposed to work.
If you really want to use this style, you can rewrite the code to get it to return a null pointer in case of failure:
int *ptr = new(nothrow) int[1000];
if (ptr == NULL) {
// Handle error cases here...
}
In most cases, you shouldn't be using new directly anyway -- you should really use std::vector<int> p(1000); and be done with it.
With that out of the way, I feel obliged to add that for an awful lot of code, it probably makes the most sense to do neither and simply assume that the memory allocation will succeed.
At one time (MS-DOS) it was fairly common for memory allocation to actually fail if you tried to allocate more memory than was available -- but that was a long time ago. Nowadays, things aren't so simple (as a rule). Current systems use virtual memory, which makes the situation much more complicated.
On Linux, what'll typically happen is that even the memory isn't really available, Linux will do what's called an "overdcommit". You'll still get a non-null pointer as if the allocation had succeeded -- but when you try to use the memory, bad things will happen. Specifically, Linux has what's called an "OOM Killer" that basically assumes that running out of memory is a sign of a bug, so if it happens, it tries to find the buggy program(s), and kills it/them. For most practical purpose, this means your program will probably be killed, and other (semi-arbitrarily chosen) ones may be as well.
Windows stays a little closer to the model C++ expects, so if (for example) your code were running on an unattended server, the allocation might actually fail. Long before it fails, however, it'll drag the rest of the machine to its knees, madly swapping in a doomed attempt at making the allocation succeed. If the user is actually operating the machine at the time, they'll typically either kill your program or else kill some others to free up enough memory for your code to get the requested memory fairly quickly.
In none of these cases is it particularly realistic to program against the assumption that an allocation can fail though. For most practical purposes, one of two things happens: either the allocation succeeds, or the program dies.
That leads back to the previous advice: in a typical case, you should generally just use std::vector, and assume your allocation will succeed. If you need to provide availability beyond that, you just about need to do it some other way (such as re-starting the process if it dies, preferably in a way that uses less memory).
As already mentioned, your original if-else example would still throw an exception from C++98 onwards, though adding nothrow (as edited) should make it work as desired (return null, thus trigger if-statement).
Below I'll assume, for simplicity, that, for if-else to handle exceptions, we have functions returning false on exception.
Some advantages of exceptions above if-else, off the top of my head:
You know the type of the exception for logging / debugging / bug fixing
Example:
When a function throws an exception, you can, to a reasonable extent, tell whether there may be a problem with the code or something that you can't do much about like an out of memory exception.
With the if-else, when a function returns false, you have no idea what happened in that function.
You can of course have separate logging to record this information, but why not just return an exception with the exception details included instead?
You needn't have a mess of if-else conditions to propagate the exception to the calling function
Example: (comments included to indicate behaviour)
bool someFunction() // may return false on exception
{
if (someFunction2()) // may return false on exception
return false;
if (someFunction3()) // may return false on exception
return false;
return someFunction4(); // may return false on exception
}
(There are many people who don't like having functions with multiple return statements. In this case, you'll have an even messier function.)
As opposed to:
void someFunction() // may throw exception
{
someFunction2(); // may throw exception
someFunction3(); // may throw exception
someFunction4(); // may throw exception
}
An alternative to, or extension of, if-else is error codes. For this, the second point will remain. See this for more on the comparison between that and exceptions.
If you handle the error locally, if ... else is cleaner. If the function where the error occurs doesn't handle the error, then throw an exception to pass off to someone higher in the call chain.
First of all your first code with if statement will terminate program in case of exception thrown by new[] operator because of not handled exception. You can check such thing here for example: http://www.cplusplus.com/reference/new/operator%20new%5B%5D/
Also exceptions are thrown in many other cases, not only when allocation failed and their main feature (in my eyes) is moving control in application up (to place where exception is handled). I recommend you read some more about exceptions, good read would be "More Effective C++" by Scott Meyers, there is great chapter on exceptions.

On null pointer arg, better to crash or throw exception? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
design by contract tests by assert or by exception?
What is the preferred way to handle a null pointer passed in as an output argument to a function? I could ASSERT but I feel like its not good to let a library crash the program. Instead, I was thinking about using exceptions.
Throw an exception! That's what they're for. Then the user of your library can decide if they want to handle it gracefully or crash and burn.
Another specific solution is to return an invalid value of a valid type, such as a negative integer for a method returning an index, but you can only use that in specific cases.
I would use an assertion if null pointers are not allowed. If you throw an exception for null pointers, you effectively allow them as arguments, because you specify behavior for such arguments. If you don't allow null pointers but you still get them, then some code around definitely has a bug. So in my opinion it does not make sense to "handle" it at some higher levels.
Either you want to allow callers to pass null pointers and handle this case by throwing an exception and let the caller react properly (or let the exception propagate, as the caller wishes), or you don't allow null pointers and assert them, possibly crashing in release mode (undefined behavior) or use a designated assertion macro that is still active in release mode. The latter philosophy is taken by functions such as strlen, while the former philosophy is taken by functions such as vector<>::at. The latter function explicitly dictates the behavior for out-of-bound values, while the former simply declares behavior undefined for a null pointer being passed.
In the end, how would you "handle" null pointers anyway?
try {
process(data);
} catch(NullPointerException &e) {
process(getNonNullData());
}
That's plain ugly, in my opinion. If you assert in the function that pointers are null, such code becomes
if(!data) {
process(getNonNullData());
} else {
process(data);
}
I think this is far superior, as it doesn't use exceptions for control flow (supplying a non-NULL source as argument). If you don't handle the exception, then you could aswell fail already with an assertion in process, which will directly point you to the file and line number the crash occurred at (and with a debugger, you can actually get a stack trace).
In my applications, i always take the assert route. My philosophy is that null pointer arguments should be handled completely by non-exceptional paths, or asserted to be non-NULL.
Do both.
Any that can be caught during development will abort the process which will make it obvious to the developer that they need to fix it.
And if one does make it past testing, there's still the exception that a robust program can handle.
And this is easy enough to put into a macro (must be a macro and not an inline so that assert properly reports the line number - thanks to #RogerPate for pointing out this out):
#define require_not_null(ptr) \
do { assert(ptr); if (!(ptr)) throw std::logic_error("null ptr"); } while (0)
If you value performance, assertions will be off in release. They're there to catch problems that should never happen, and shouldn't be used to catch stuff that may happen in real life. That's what exceptions are for.
But let's back up a second. Where is it guaranteed what will happen if you dereference a null pointer, whether writing to it or not? It may crash for you, but it won't crash in every OS, or every compiler, or any anything else. That it crashes for you is just good fortune on your part.
I'd say throw an exception if you're not gonna create the object yourself and have the pointer to the pointer passed to you, the way I often see 'out' params passed.
If you are programming the autopilot system for the ultimate airplane, I should recommend trying to handle the exception gracefully.
Please read the Eiffel specifications for "contract programming" (a very nice language indeed) and you'll be enlightened. NEVER crash if you can handle the event.
if you throw, a client can decide to re-throw, or not handle the exception, or crash or call exit or try to recover or....
If you crash, the client crashes with you.
So throw, to give your client more flexibility.
I would neither raise an exception nor use assert, which is what the C++ Standard library does. Consider about the simplest function in the library, strlen(). If it raised an exception, how would you possibly handle it? And the assertions won't fire in production code. The only sensible thing to do is say explicitly that the function must not be called with a NULL pointer as a parameter, and that doing so will result in undefined behaviour.
The benefit of using exceptions is that you let your client code decide how to handle the exceptional circumstance. That's for the case where the parameter being non-null is a stated precondition of the function. For functions taking optional out parameters, though, passing NULL can be an indication that the client is not interested in the value. Presumably, you're using the return value to signify success or failure, and if that's the case, you could simply detect the NULL and return an error code if the parameter is mandatory, or simply ignore it if the parameter is optional. This avoids the overhead of exceptions and still allows error handling on the client's part.

Wrapping C in C++, just for try/catch

So, I have a big piece of legacy software, coded in C. It's for an embedded system, so if something goes wrong, like divide by zero, null pointer dereference, etc, there's not much to do except reboot.
I was wondering if I could implement just main() as c++ and wrap it's contents in try/catch. That way, depending on the type of exception thrown, I could log some debug info just before reboot.
Hmm, since there are multiple processes I might have to wrap each one, not just main(), but I hope that you see what I mean...
Is it worthwhile to leave the existing C code (several 100 Klocs) untouched, except for wrapping it with try/catch?
Division by zero or null pointer dereferencing don't produce exceptions (using the C++ terminology). C doesn't even have a concept of exceptions. If you are on an UNIX-like system, you might want to install signal handlers (SIGFPE, SIGSEGV, etc.).
Since it's an embedded application it probably runs only on one platform.
If so its probably much simpler and less intrusive to install a proper interrupt handler / kernel trap handler for the division by zero and other hard exceptions.
In most cases this can be done with just a few lines of code. Check if the OS supports such installable exception handlers. If you're working on an OS-less system you can directly hook the CPU interrupts that are called during exceptions.
First of all, divide by zero or null pointer dereference won't throw exceptions. Fpe exceptions are implemented in the GNU C library with signals (SIGFPE). And are part of the C99 standard, not the C++ standard.
A few hints based in my experience in embedded C and C++ development. Depending on your embedded OS:
Unless you are absolutely sure of what you are doing, don't try/catch between threads . Only inside the same thread. Each thread usually has its own stack.
Throwing in the middle of legacy C code and catching, is going to lead to problems, since for example when you have jumped to the catch block out of the normal program flow, allocated memory may not be reclaimed, thus you have leaks which is far more problematic than divide by zero or null pointer dereference in an embedded system.
If you are going to use exceptions, throw them inside your C++ code with allocation of other "C" resources in constructors and deallocation in destructors.
Catch them just above the C++ layer.
I don't think machine code compiled from C does the same thing with regard to exceptions, as machine code compiled for C++ which "knows" about exceptions. That is, I don't think it's correct to expect to be able to catch "exceptions" from C code using C++ constructs. C doesn't throw exceptions, and there's nothing that guarantees that errors that happen when C code does something bad are caught by C++'s exception mechanism.
Divide by zero, null pointer dereference are not C or C++ exceptions they are hardware exceptions.
On Windows you can get hardware exceptions like these wrapped in a normal C++ exception if _set_se_translator() is used.
__try/__catch may also help. Look up __try/__catch, GetExceptionCode(), _set_se_translator() on MSDN, you may find what you need.
I think I remember researching on how to handle SIGSEGV ( usually generated when derefing invalid pointer, or dividing by 0 ) and the general advise I found on the net was: do nothing, let the program die. The explanation, I think a correct one, is that by the time you get to a SIGSEGV trap, the stack of the offending thread is trashed beyond repair.
Can someone comment if this is true?
Only work on msvc
__try
{
int p = 0;
p=p / 0;
}
__except (1)
{
printf("Division by 0 \n");
}

Can I use the STL if I cannot afford the slow performance when exceptions are thrown?

For example, I'm writing a multi-threaded time-critical application that processes and streams audio in real-time. Interruptions in the audio are totally unacceptable. Does this mean I cannot use the STL because of the potential slow down when an exception is thrown?
Generally, the only exceptions that STL containers will throw by themselves is an std::bad_alloc if new fails. The only other times are when user code (for example constructors, assignments, copy constructors) throws. If your user code never throws then you only have to guard against new throwing, which you would have had to do anyways most likely.
Other things that can throw exceptions:
- at() functions can throw std::out_of_range if you access them out of bounds. This is a serious program error anyways.
Secondly, exceptions aren't always slow. If an exception occurs in your audio processing, its probably because of a serious error that you will need to handle anyways. The error handling code is probably going to be significantly more expensive than the exception handling code to transport the exception to the catch site.
If an STL container throws, you are probably having much bigger problem than the slow down :)
It's not clearly written in the previous answers, so:
Exceptions happen in C++
Using the STL or not won't remove the RAII code that will free the objects's resources you allocated.
For example:
void doSomething()
{
MyString str ;
doSomethingElse() ;
}
In the code above, the compiler will generate the code to free the MyString resources (i.e. will call the MyString destructor), no matter what happens in the meantime including if if an exception is thrown by doSomethingElse or if you do a "return" before the end of the function scope.
If you have a problem with that, then either you should revise your mindset, or try C.
Exceptions are supposed to be exceptional
Usually, when an exception occurs (and only when), you'll have a performance hit.
But then, the exception should only sent when:
You have an exceptional event to handle (i.e. some kind of error)
In very exceptional cases (i.e. a "massive return" from multiple function call in the stack, like when doing a complicated search, or unwinding the stack prior a thread graceful interruption)
The keyword here is "exceptional", which is good because we are discussing "exception" (see the pattern?).
In your case, if you have an exception thrown, chances are good something so bad happened your program would have crashed anyway without exception.
In this case, your problem is not dealing with the performance hit. It is to deal with a graceful handling of the error, or, at worse, graceful termination of your program (including a "Sorry" messagebox, saving unsaved data into a temporary file for later recovery, etc.).
This means (unless in very exceptional cases), don't use exceptions as "return data". Throw exceptions when something very bad happens. Catch an exception only if you know what to do with that. Avoid try/catching (unless you know how to handle the exception).
What about the STL ?
Now that we know that:
You still want to use C++
Your aim is not to throw thousand exceptions each and every seconds just for the fun of it
We should discuss STL:
STL will (if possible) usually verify if you're doing something wrong with it. And if you do, it will throw an exception. Still, in C++, you usually won't pay for something you won't use.
An example of that is the access to a vector data.
If you know you won't go out of bounds, then you should use the operator [].
If you know you won't verify the bounds, then you should use the method at().
Example A:
typedef std::vector<std::string> Vector ;
void outputAllData(const Vector & aString)
{
for(Vector::size_type i = 0, iMax = aString.size() ; i != iMax ; ++i)
{
std::cout << i << " : " << aString[i] << std::endl ;
}
}
Example B:
typedef std::vector<std::string> Vector ;
void outputSomeData(const Vector & aString, Vector::size_type iIndex)
{
std::cout << iIndex << " : " << aString.at(iIndex) << std::endl ;
}
The example A "trust" the programmer, and no time will be lost in verification (and thus, less chance of an exception thrown at that time if there is an error anyway... Which usually means the error/exception/crash will usually happen after, which won't help debugging and will let more data be corrupted).
The example B asks the vector to verify the index is correct, and throw an exception if not.
The choice is yours.
Do not be afraid of exceptions with regard to performance.
In the old days of C++ a build with exceptions enabled could be a lot slower on some compilers.
These days it really does not matter if your build with or without exception handling.
In general STL does not throw exceptions unless you run out of memory so that should not be a problem for your type of application either.
(Now do not use a language with GC.....)
It's worth noting a couple of points:
Your application is multi-threaded. If one thread (maybe a GUI one) is slowed down by an exception, it should not affect the performance of the real-time threads.
Exceptions are for exceptional circumstances. If an exception is thrown in your real-time thread, the chances are it will mean that you couldn't continue playing audio anyway. If you find for whatever reason that you are continually processing exceptions in those threads, redesign to avoid the exceptions in the first place.
I'd recommend you accept the STL with it's exceptions (unless the STL itself proves too slow - but remember: measure first, optimise second), and also to adopt exception handling for your own 'exceptional situations' (audio hardware failure, whatever) in your application.
I'm struggling to think which portions of the STL specify that they can raise an exception. In my experience most error handling is handled by return codes or as a prerequisite of the STL's use.
An object passed to the STL could definitely raise an exception, e.g. copy constructor, but that would be an issue regardless of the use of STL.
Others have mentioned functions such as std::vector::at() but you can perform a check or use an alternate method usually to ensure no exception can be thrown.
Certainly a particular implementation of the STL can performs "checks", generally for debug builds, on your use of the STL, I think it will raise an assertion only, but perhaps some will throw an exception.
If there is no try/catch present I believe no/minimal performance hit will be incurred unless an exception is raised by your own classes.
On Visual Studio you can disable the use of C++ exceptions entirely see Project Properties -> C/C++ -> Code Generation -> Enable C++ Exceptions. I presume this is available on most C++ platforms.
You talk as if exceptions are inevitable. Simply don't do anything that could cause an exception -- fix your bugs, verify your inputs.