Short answer: you can't because most work of exception handling is done outside of your program, and is therefore outside of gdb's scope.
Explained answer:
sometimes the line an exception is thrown has no symbols
If the binary you're debugging has no debug symbols then the binary is probably stripped and you won't be able to find much at all about the types/values of anything at all.
How do I inspect the value of the current exception?
I think you're assuming here that an exception is a language feature that gdb can inspect; in fact an exception in C++ is a combination of features from C++ as a language, of libc++ and the ABI. And there might even be more than a single active current exception.
Like UpAndAdam points out you can set a breakpoint in a catch block with a type specifier, and then inspect that element, but I suspect your problem is in cases where you find a "catch (...)". In those cases you won't be able to learn much about the current exception unless you go digging into the implementation of exception handling.
With a very short and incomplete description we could say that to throw an exception:
- Your program will call libc++ to raise an exception
- libc++ will call "unwind" in glibc to start the stack unwinding
- unwind will call back a "personality function" from libc++ for each stack frame (each function call in the stack, basically)
- the personality function will somehow decide if the current stack frame can or can't handle this exception
- if the exception can be handled the catch block will be executed
Now, it's difficult to talk about details because a lot of exception handling depends on your toolchain (compiler, platform, architecture, libc++, etc) but in most cases a "catch (...)" won't even receive the original exception as an argument. In any case, to somehow answer your question: in gcc with gnu's libc++ you could try something like this:
- Get a libc++ with debugging symbols
- Set a breakpoint in __gxx_personality_v0 (that's called the personality function). This function will get called to determine whether a stack frame (a function call, basically) has a suitable catch block to handle the exception
- In the personality function you'll be able to find a pointer to _Unwind_Exception, which is a wrapper to your real exception
- Get the type info for your exception like this:
__cxa_exception *exception_header = (__cxa_exception*)(unwind_exception+1)-1;
std::type_info *thrown_exception_type = exception_header->exceptionType;
- You'll get an exception type which you can then lookup with the rest of the RTTI defined for your code
In any case, you'll probably need to spend quite a bit of time trying to understand how exception handling is implemented in your platform. If you want to read a bit more about exception handling I spent some time in the past writing about the topic @ http://monoinfinito.wordpress.com/series/exception-handling-in-c/. It's not an official source but it does have links to the specs of each part involved in handling an exception.