I use a crash reporting feature that allows the user to submit a crash report if the application crashed with an uncaught exception.
After adopting C++20 coroutines entered the application.
If there is an unexpected exception thrown in a coroutine the exception is caught before it is rethrown.
This causes crashreports to not show the stacktrace needed to figure out what happened, but only the stacktrace to the coroutine that rethrew the exception. This basically makes any crash reporting useless.
As far as I could find there is no way to prevent the catching of any exceptions by the coroutine because it is a required part of the design.
Is there a way to improve this I cant see?
I am curious because I found nobody else complaining yet. :->
Edit: To clarify the app is running on Windows, I mean the stacktrace of a minidump that is created at the point of the unhandled exception using: SetUnhandledExceptionFilter + MiniDumpWriteDump
C++ does not have standard stack tracing yet, so there is no nice builtin way to do this.
However, there are ways, which rely on keeping information in the promise objects.
Clang has documentation for some common debugging methods for coroutines.
The best solution we have found is as follows (Windows specific!):
Until now we used SetUnhandledExceptionFilter at the start of the app to set an exceptionfilter function that writes a minidump.
Instead we now use _set_se_translator.
If we want the program to just crash (f.e. if windows is set to write dumps) we set a function which calls std::abort.
If we want to handle it interactively we set a function which asks the user whether to send a minidump, the dump is written as before at this point.
Both cases provide the full callstack in the dump.
The only downside remaining is we cant let the program crash for "normal" exceptions to dump, this was possible before. But the "most important" exceptions (f.e. access violations) work.
I am trying to build a Fortran program, but I get errors about an undefined reference or an unresolved external symbol. I've seen another question about these errors, but the answers there are mostly specific to C++.
What are common causes of these errors when writing in Fortran, and how do I fix/prevent them?
This is a canonical question for a whole class of errors when building Fortran programs. If you've been referred here or had your question closed as a duplicate of this one, you may need to read one or more of several answers. Start with this answer which acts as a table of contents for solutions provided.
A link-time error like these messages can be for many of the same reasons as for more general uses of the linker, rather than just having compiled a Fortran program. Some of these are covered in the linked question about C++ linking and in another answer here: failing to specify the library, or providing them in the wrong order.
However, there are common mistakes in writing a Fortran program that can lead to link errors.
Unsupported intrinsics
If a subroutine reference is intended to refer to an intrinsic subroutine then this can lead to a link-time error if that subroutine intrinsic isn't offered by the compiler: it is taken to be an external subroutine.
implicit none
call unsupported_intrinsic
end
With unsupported_intrinsic not provided by the compiler we may see a linking error message like
undefined reference to `unsupported_intrinsic_'
If we are using a non-standard, or not commonly implemented, intrinsic we can help our compiler report this in a couple of ways:
implicit none
intrinsic :: my_intrinsic
call my_intrinsic
end program
If my_intrinsic isn't a supported intrinsic, then the compiler will complain with a helpful message:
Error: ‘my_intrinsic’ declared INTRINSIC at (1) does not exist
We don't have this problem with intrinsic functions because we are using implicit none:
implicit none
print *, my_intrinsic()
end
Error: Function ‘my_intrinsic’ at (1) has no IMPLICIT type
With some compilers we can use the Fortran 2018 implicit statement to do the same for subroutines
implicit none (external)
call my_intrinsic
end
Error: Procedure ‘my_intrinsic’ called at (1) is not explicitly declared
Note that it may be necessary to specify a compiler option when compiling to request the compiler support non-standard intrinsics (such as gfortran's -fdec-math). Equally, if you are requesting conformance to a particular language revision but using an intrinsic introduced in a later revision it may be necessary to change the conformance request. For example, compiling
intrinsic move_alloc
end
with gfortran and -std=f95:
intrinsic move_alloc
1
Error: The intrinsic ‘move_alloc’ declared INTRINSIC at (1) is not available in the current standard settings but new in Fortran 2003. Use an appropriate ‘-std=*’ option or enable ‘-fall-intrinsics’ in order to use it.
External procedure instead of module procedure
Just as we can try to use a module procedure in a program, but forget to give the object defining it to the linker, we can accidentally tell the compiler to use an external procedure (with a different link symbol name) instead of the module procedure:
module mod
implicit none
contains
integer function sub()
sub = 1
end function
end module
use mod, only :
implicit none
integer :: sub
print *, sub()
end
Or we could forget to use the module at all. Equally, we often see this when mistakenly referring to external procedures instead of sibling module procedures.
Using implicit none (external) can help us when we forget to use a module but this won't capture the case here where we explicitly declare the function to be an external one. We have to be careful, but if we see a link error like
undefined reference to `sub_'
then we should think we've referred to an external procedure sub instead of a module procedure: there's the absence of any name mangling for "module namespaces". That's a strong hint where we should be looking.
Mis-specified binding label
If we are interoperating with C then we can specify the link names of symbols incorrectly quite easily. It's so easy when not using the standard interoperability facility that I won't bother pointing this out. If you see link errors relating to what should be C functions, check carefully.
If using the standard facility there are still ways to trip up. Case sensitivity is one way: link symbol names are case sensitive, but your Fortran compiler has to be told the case if it's not all lower:
interface
function F() bind(c)
use, intrinsic :: iso_c_binding, only : c_int
integer(c_int) :: f
end function f
end interface
print *, F()
end
tells the Fortran compiler to ask the linker about a symbol f, even though we've called it F here. If the symbol really is called F, we need to say that explicitly:
interface
function F() bind(c, name='F')
use, intrinsic :: iso_c_binding, only : c_int
integer(c_int) :: f
end function f
end interface
print *, F()
end
If you see link errors which differ by case, check your binding labels.
The same holds for data objects with binding labels, and also make sure that any data object with linkage association has matching name in any C definition and link object.
Equally, forgetting to specify C interoperability with bind(c) means the linker may look for a mangled name with a trailing underscore or two (depending on compiler and its options). If you're trying to link against a C function cfunc but the linker complains about cfunc_, check you've said bind(c).
Not providing a main program
A compiler will often assume, unless told otherwise, that it's compiling a main program in order to generate (with the linker) an executable. If we aren't compiling a main program that's not what we want. That is, if we're compiling a module or external subprogram, for later use:
module mod
implicit none
contains
integer function f()
f = 1
end function f
end module
subroutine s()
end subroutine s
we may get a message like
undefined reference to `main'
This means that we need to tell the compiler that we aren't providing a Fortran main program. This will often be with the -c flag, but there will be a different option if trying to build a library object. The compiler documentation will give the appropriate options in this case.
There are many possible ways you can see an error like this. You may see it when trying to build your program (link error) or when running it (load error). Unfortunately, there's rarely a simple way to see which cause of your error you have.
This answer provides a summary of and links to the other answers to help you navigate. You may need to read all answers to solve your problem.
The most common cause of getting a link error like this is that you haven't correctly specified external dependencies or do not put all parts of your code together correctly.
When trying to run your program you may have a missing or incompatible runtime library.
If building fails and you have specified external dependencies, you may have a programming error which means that the compiler is looking for the wrong thing.
Not linking the library (properly)
The most common reason for the undefined reference/unresolved external symbol error is the failure to link the library that provides the symbol (most often a function or subroutine).
For example, when a subroutine from the BLAS library, like DGEMM is used, the library that provides this subroutine must be used in the linking step.
In the most simple use cases, the linking is combined with compilation:
gfortran my_source.f90 -lblas
The -lblas tells the linker (here invoked by the compiler) to link the libblas library. It can be a dynamic library (.so, .dll) or a static library (.a, .lib).
In many cases, it will be necessary to provide the library object defining the subroutine after the object requesting it. So, the linking above may succeed where switching the command line options (gfortran -lblas my_source.f90) may fail.
Note that the name of the library can be different as there are multiple implementations of BLAS (MKL, OpenBLAS, GotoBLAS,...).
But it will always be shortened from lib... to l... as in liopenblas.so and -lopenblas.
If the library is in a location where the linker does not see it, you can use the -L flag to explicitly add the directory for the linker to consider, e.g.:
gfortran -L/usr/local/lib -lopenblas
You can also try to add the path into some environment variable the linker searches, such as LIBRARY_PATH, e.g.:
export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/lib
When linking and compilation are separated, the library is linked in the linking step:
gfortran -c my_source.f90 -o my_source.o
gfortran my_source.o -lblas
Not providing the module object file when linking
We have a module in a separate file module.f90 and the main program program.f90.
If we do
gfortran -c module.f90
gfortran program.f90 -o program
we receive an undefined reference error for the procedures contained in the module.
If we want to keep separate compilation steps, we need to link the compiled module object file
gfortran -c module.f90
gfortran module.o program.f90 -o program
or, when separating the linking step completely
gfortran -c module.f90
gfortran -c program.f90
gfortran module.o program.o -o program
Problems with the compiler's own libraries
Most Fortran compilers need to link your code against their own libraries. This should happen automatically without you needing to intervene, but this can fail for a number of reasons.
If you are compiling with gfortran, this problem will manifest as undefined references to symbols in libgfortran, which are all named _gfortran_.... These error messages will look like
undefined reference to '_gfortran_...'
The solution to this problem depends on its cause:
The compiler library is not installed
The compiler library should have been installed automatically when you installed the compiler. If the compiler did not install correctly, this may not have happened.
This can be solved by correctly installing the library, by correctly installing the compiler. It may be worth uninstalling the incorrectly installed compiler to avoid conflicts.
N.B. proceed with caution when uninstalling a compiler: if you uninstall the system compiler it may uninstall other necessary programs, and may render other programs unusable.
The compiler cannot find the compiler library
If the compiler library is installed in a non-standard location, the compiler may be unable to find it. You can tell the compiler where the library is using LD_LIBRARY_PATH, e.g. as
export LD_LIBRARY_PATH="/path/to/library:$LD_LIBRARY_PATH"
If you can't find the compiler library yourself, you may need to install a new copy.
The compiler and the compiler library are incompatible
If you have multiple versions of the compiler installed, you probably also have multiple versions of the compiler library installed. These may not be compatible, and the compiler might find the wrong library version.
This can be solved by pointing the compiler to the correct library version, e.g. by using LD_LIBRARY_PATH as above.
The Fortran compiler is not used for linking
If you are linking invoking the linker directly, or indirectly through a C (or other) compiler, then you may need to tell this compiler/linker to include the Fortran compiler's runtime library. For example, if using GCC's C frontend:
gcc -o program fortran_object.o c_object.o -lgfortran
when i search this on google then it show that error means compile time error and exception is runtime error? but i think that it is not that so....
That is generally correct. Although the terms are colloquially interchangeable in many domains.
An Error, also known as a compile-time error, is a statement of fact. (Or NOT fact) The compiler is unable to compile the output.
Technically an error is a state in code that has raised an exception in the compiler's runtime :)
An Exception is raised at runtime and is the result of an exceptional combination of values.
Because an Exception is raised at runtime, we can generally write code to catch and handle or workaround an exception within your script or code. An Error prevents the code from being compiled and thus executed at all, so our only option is to modify the code to resolve an Error.
A compiler may perform syntax and sometimes type checking to ensure that the code follows a set of pre-determined rules and can be compiled into executable statements, but it is not until invalid values are passed into those statements that an Exception can occur, that is harder for a compiler to do and so is generally only detected at Runtime.
Some advanced or specialised compilers may perform checks against common values and as a programer you can write unit tests to try and pre-emptively detect exceptions before releasing your code.
Exceptions and Errors are the same things. Somewhere in software history, someone came up with the phrase “Exceptions are exceptional”. That sounds catchy but it doesn’t translate to Exceptions and Errors. If you go that route then who decides what is Exceptional? It is very subjective an error for one context could be exceptional to one and not to another. Exceptional and Exception are very different words. Someone apparently thought the catchy phrase enforces the idea that there is a difference.
They are the same thing. I’m not a Java developer and I realize it has different classes for each but in the .NET world they are the same thing. The preferred error handling framework in .NET is the Exception class. It doesn’t care what you want to call it, an error or an exception. Nor does it care if it is exceptional or not. It is just a vehicle for communicating error information. You can communicate the severity of an error by creating and using classes that inherit from Exception.
The Source of my information is here:
Cwalina, K., Abrams, B. F., Barton, J., Icaza, M. de, & Hejlsberg, A. (2020). Framework design guidelines: Conventions, idioms, and patterns for reusable .net libraries. Addison-Wesley.
Everyone (at least everyone who uses a compiled language) has faced compilation errors but how many times do you get to actually crash the compiler?
I've had my fair share of "internal compiler errors" but most went away just by re-compiling. Do you have a (minimal) piece of code that crashes the compiler?
I write the compiler we use, so it crashes sometimes.
easy.
// -*- C++ -*-
template <int n>
class Foo : public Foo<n+1>
{
};
int main(int, char*[])
{
Foo<0> x;
return 0;
};
ejgottl#luna:~/tmp$ g++ -ftemplate-depth-1000000 -Wall foo.cpp -o foo
g++: Internal error: Segmentation fault (program cc1plus)
Please submit a full bug report.
See `<URL:http://gcc.gnu.org/bugs.html>` for instructions.
For Debian GNU/Linux specific bug reporting instructions, see
`<URL:file:///usr/share/doc/gcc-4.2/README.Bugs>`.
I haven't made GHC (a Haskell compiler) crash yet, but I've gotten it to error out with a
My brain just exploded.
I can't handle pattern bindings for existentially-quantified constructors.
It's pretty easy to work around, and you don't hit this unless you have some tricky (and usually wrong) design, but it probably wins as the best compiler error message ever.
VC catches it gracefully now, but in the mid 90's, this would crashed both Microsoft C++ and Borland C++ compilers:
struct MyClass
{
MyClass operator->() { return *this; }
};
int main(int argc, char* argv[])
{
MyClass A;
A->x;
}
An overloaded operator-> is intrinsically recursive. The function is expected to return a pointer, which oper-> is again applied to. This fragment made code generation infinitely recursive.
Actionscript 3.0:
switch(on_some_variable)
{
}
Empty switch = Kaboom!
Visual C++ 9.0 SP1
this just happened to me
------ Build started: Project: pdfp, Configuration: Debug Win32 ------
Compiling...
reader.cpp
xref.cpp
c:\projects\pdfp\xref.cpp(52) : fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'f:\dd\vctools\compiler\cxxfe\sl\p1\c\toil.c', line 8569)
To work around this problem, try simplifying or changing the program near the locations listed above.
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
Generating Code...
Build log was saved at "file://c:\Projects\pdfp\Debug\BuildLog.htm"
pdfp - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Well, this didn't actually crash the compiler -- It was merely a bug were VC++ wouldn't accept perfectly good code. (details provided here).
The odd this about it was that it was only triggered when three fairly obscure conditions were all met. Moving one line of code was all that was needed for an effective workaround. And one of the needed pre-conditions was "using namespace std;" which is widely discouraged in production code.
Nevertheless, messages asking how to fix the problem were a staple on Microsoft VC++ newsgroups. I couldn't figure out how so many people stumbled onto an obscure bug. So, eventually, I asked someone.....
The exact code needed to trigger the bug was an example in Stroustrup's "The C++ Programming Langauge". (*)
(*) Note, I'm not saying he did it on purpose. I sure he tested it under a UNIX variant of C++, and was completely unaware of it's affect on VC++.
I've seen a few compiler bugs in the C# compiler (all edge cases, all reported appropriately) and confirmed some crashes provoked by other people.
The scariest compiler (of a sort) bug I've encountered was a JIT bug in one version of Java. It was quite reproducible, but caused the VM to go down. Adding a fairly no-op statement (I can't remember exactly what offhand - possibly just declaring an extra local variable with an initial value) moved it away from whatever corner case it happened to be - and it was fixed in a later version.
This crashed the C64 BASIC:
PRINT 0 + "" +- 0
Yes, especially when it's an old or undermaintained compiler (GCC 2.95, Tendra in C++ mode). I don't keep the pieces of code around, though.
Visual C++ 5. 'Nuff said.
Oops, forgot an 'e' in typedef and crashed the compiler.
typdef struct kGUIColor GameColor;
c:\source\kgui\samples\space\space.cpp(35) : fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 2708)
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
Today VS2003SP1 gave me a C1001 (Internal Compiler Error) complaining about compiler file 'msc1.cpp', line 2708) because of this:
struct PATTERN {
…
};
It turns out that the problem was that the structure name I was trying to define (PATTERN) was already a typedef in the GDI for a brush type. However instead of telling me that the symbol is already defined (like it does for most other things) it not only did not point to the structure as the problem—I narrowed the problem down to it by selectively commenting out blocks until the error went away—but it also gave me the aforementioned cryptic error which has nothing to do with the file specified—which I can’t even find to examine the line in question. :|
I was able to reproduce it with the following code:
typedef int SOMETHINGOROTHER;
struct SOMETHINGOROTHER {};
> fatal error C1001: INTERNAL COMPILER ERROR
> (compiler file 'msc1.cpp', line 2708) …
Whereas the following code gives the expected error message:
struct SOMETHINGOROTHER {};
typedef int SOMETHINGOROTHER;
> 'SOMETHINGOROTHER' : redefinition; different basic types
Clearly the problem is in the compiler’s structure handling routine.
I wonder if VS2005+ do better…
Here's a way to crash the VS2003 C++ compiler.
typedef map<int,int> Tmap;
private: Tmap; * m_map;
This will result in a crash and the following error message
fatal error C1001: INTERNAL COMPILER
ERROR (compiler file 'msc1.cpp', line
2708) Please choose the Technical
Support command on the Visual C++ Help
menu, or open the Technical Support
help file for more information
Remove the semicolon immediately after Tmap (second line which defines m_map) to eliminate the error.
In a project I was working in, some specific usages of Boost Lambda expressions could make the Visual C++ compiler crash. (We were using Visual Studio 2003)
The compiler would only crash during the release build, a debug build would work fine.
There had been a religious war raging through the team about the appropriate usage of the lambda libraries, I was almost grateful that the compiler settled it for us. :-)
In version 1.2.x of the Mono C# compiler would crash quite a bit with complicated code (if I remember correctly, nested anonymous delegates). Fortunately with 2.x release, I haven't seen any crashes.
At my previous job we had a simulator which was notorious for being able to crash (ICE) compilers or cause them to generate incorrect code. And when the code actually was generated correctly, ofter the compiler took 15 minutes for a single source file. Visual Studio was never (as long as I worked there) able to compile the simulator core.
The core was automatically generated from a DSL, and the generated code often pushed the compiler to its limits.
Upgrading to a new version of GCC often caused widespread nervosity: will the new version work?
Thanks to #Nick, this crashes VS2005.
template<typename Res, typename T>
Res operator_cast(const T& t)
{
return t.operator Res();
}
int main()
{
return operator_cast<int>(0);
}
I've crashed a compiler before by running it out of memory.
Give a DOS compiler about 0.5mb of source code. Crunch.
When you get a message "Catastrophic Failure" you know you're trying....
Michael
I use both pcc and gcc to compile my old OS project.
I found a bug with how both pcc and gcc handle a non-trivial piece of code and it crashed pcc.
(chars are signed on my platform)
struct{
char myvalue:1;
}mystruct;
pcc crashed because all bitfield values must be int though, so it's really more buggy there, but gcc handles it wrongly. See, if you think about it, it is signed, but only has room for one bit. So therefore, it only can store 0 and -1. Well, gcc handles it wrong by storing 0 or 1.
VC++ has crashed on me when compiling C++ if template usage is messed up (e.g., missing out on a closing ">").
I did. Some Delphi versions (lets say #4) crashed very often with cryptic error messages.
The newer versions (2006 and more) are stable but not rock solid. (7 was great in that case).
Compiler crashes often occur with large edits, and debug sessions of complex projects (lots of dll's). Most of the time a restart of the ide is enough. But sometimes you need to restart the PC.
O and I once crashed OS2 along with the compiler because the swapfile grew too large.
One time when I used the generators example from the Python docs, it broke the version of Python we were using. The same week, one of my colleagues managed to misuse the FFI such that any calculation involving the number 3 would crash python.
The Microsoft Xbox 360 compiler can crash easily. I was given source code with Japanese comments and when converted to regular text one of the last characters on the line was a '\' so it continued the comment onto the next line. If the next line was a switch command, then the compiler crashes.
//wierd japanese characters here %^$$\
switch(n)
{
case 0:
.....
break;
case 1:
.....
break;
}
I have crashed Delphi 7 many times asking it to compile legacy dos code.
The prime culprit seems to be any qualification of something as being in the system unit. This won't always blow it up but when it blows up on such stuff I look through and rewrite anything that requires such an override and the problem goes away.
The blowups are 100% reproduceable but I have never managed to make a simple test case. It doesn't actually crash the compiler most of the time, you usually get an error that has nothing to do with the problem and may be hundreds of lines from it. The environment is destabilized, save and exit is ok but don't think of doing anything else.
Back in the stone age with Borland Pascal 7 (the last dos version) I broke it many times. No crash, just incorrect and inconsistent code emission. I finally learned to keep the .EXE (not counting debug info) below 3mb. The farther beyond that I went the more unstable it got.
I've crashed VC++ a number of times, usually with template code. But that's not the most interesting crash...
I crashed the VS2005 Team System compiler with the /analyze option compiling my shared code library which compiled without error without the switch, and on VS2008 with and without the switch. Of course MS wasn't very interested because it was a bug in the old version of the compiler, but I thought it was pretty interesting.
I managed to segfault the Python interpreter. Of course, I was working on a C extension at the time and getting it not-quite-right.
It doesn't happen as much as it used to, but occasionally the ASP.net precompiler has issues - I haven't seen it personally, but I have fixed a problem on another project once where they had name clashes because they weren't using namespaces properly (caused compiler crashes) during pre-compile.
In the good old days (unmanaged MSVC++) we had the odd compiler crash usually due to linking in external static win32 classes (.lib) and a couple of odd bits of code occasionally caused issues, but these were all picked up very quickly.
I don't know if I would call it crashing, but sdcc (Small Device C Compiler) fails at compiling code formed in a particular way:
Target: 8051
Code had to execute in a 512 byte cache loaded from an external tester
Tester is in control and stores the code - cache can't fetch the next page
No function calls allowed - the PC (program counter) would skip to a place not resident in cache; preprocessor macros were used to accomplish modular coding practice
Jumps (branching) allowed if it doesn't skip out of the cache
No const values - in the data section of the program code which causes code in cache to fetch something not in cache - preprocessor constant (#define) OK here
The preprocessor macros are unrolled resulting in flat, but large code - everything in main(); execution skips the startup code (setting up the stack, etc) and starts at the beginning of main()
Relevant part of this answer:
Occasionally, sdcc would refuse to compile syntactically correct code, with a message about running out of memory. This even happened compiling on 64-bit boxes with 8GB of RAM.
The solution in these cases was to split the firmware into separate pieces and compile them separately and execute them separately. The pieces may have been able to be linked back together, but at that point it didn't matter.
I didn't try it, but the Keil 8051 compiler probably could have handled the problematic code.