We have a legacy code. When we compile with "-Os" optimization flag the code crashes with Segmenation fault . But when we compile "-O2" optimization flag works.
Can i know internally what all are the compiler flags enabled when -Os option is specified.
Also any pointers for debugging the issue would be helpful.
Thank you for reaching out.
> Can i know internally what all are the compiler flags enabled when -Os option is specified.
We will discuss this with the internal team and get back to you.
> Also any pointers for debugging the issue would be helpful.
Could you please share with us the following details so that we can try it from our end and suggest ways to debug the issue.
- A minimal sample reproducer code
- Steps followed to build the code
- Version of the compiler.
- Details of the environment and application.
>>Also any pointers for debugging the issue would be helpful.
If your program is made up of several source files, you can set (use) different optimization levels on each file. Manipulating these settings may help you to isolate the problematic source file.
Then, if you are lucky and the problem resides in one relatively small-ish source file, you can elect to use this with -O2 and move on, Or investigate further to isolate just what is happening and report to the developers such that they can fix the bug (assuming the bug is with the compiler).
Note, the fact that your program does not crash using -O2 but crashes using -Os is not an indication that the source of the problem was not with your code. IOW, with -O2 your error was still there, but it did not result in program crashing.
IIF you are interested in determining the problem (as it may be your coding problem), what I've done in the past, is to create two instances of the problematic function (under different names). I then instrument the code to capture intermediary results together with line number, then at the call point, call both functions (note this may require saving/restoring external data that gets modified by the function call). After the return from both calls, a difference can be performed between the two results..
Hopefully, a (soon to be fatal) divergence in results is found or a crash is observed that can be caught as an exception by your debugger, and then you can use the debugger to examine your trace tables.
I should also add, that often is the case that bugs (yours or compilers) do not cooperate with your attempts at debugging. We here refer to this type of bug as a Heisenbug (Heisenberg uncertainty principal). Meaning your attempts at observing the bug changes the outcome of the condition (bug disappears).
In these cases you have to be as canny as the cat in catching the bug.
And note, it may help to capture the original input data because the bug may be data dependent (as well as location dependent) and caused prior to entry of the bug exposing function.
Location dependent errors can be caused by pointers/references being used after having gone out of scope. When the invalid pointer points to its former location .OR. points to some arbitrary accessible location, the data at that location can be read and/or written. This can:
- use code as data
- write over code as data
- use valid other data as data
- write over other valid data as data
- use unused(formerly used) data as data
- write over unused(formerly used) data as data
all of which can go undetected. In the invalid cases above, only when the errant pointer is used to
- write to a read-only section of virtual memory
- read/write to an unmappable page
- read/write with memory alignment faults
- overwrites code that is executed later
That the bug exposes itself (crash).
Thank you for your patience.
>Can i know internally what all are the compiler flags enabled when -Os option is specified?
Os : Enables optimizations that do not increase code size; it produces smaller code size than O2. It disables some optimizations which increase code size for small speed benefit.
O2 : Enables optimizations for speed. This is the generally recommended optimization level (DEFAULT). Vectorization is enabled at O2 and higher levels.
On systems using IA-32 architecture: Some basic loop optimizations such as Distribution, Predicate Opt, Interchange, multi-versioning, and scalar replacements are performed.
O2 option also enables:
Ø Inlining of intrinsics
Ø Intra-file interprocedural optimization, which includes:
Ø constant propagation
Ø forward substitution
Ø routine attribute propagation
Ø variable address-taken analysis
Ø dead static function elimination
Ø removal of unreferenced variables
and the following capabilities for performance gain:
Ø constant propagation
Ø copy propagation
Ø dead-code elimination
Ø global register allocation
Ø global instruction scheduling and control speculation
Ø loop unrolling
Ø optimized code selection
Ø partial redundancy elimination
Ø strength reduction/induction variable simplification
Ø variable renaming
Ø exception handling optimizations
Ø tail recursions
Ø peephole optimizations
Ø structure assignment lowering and optimizations
Ø dead store elimination
This option may set other options, especially options that optimize for code speed. This is determined by the compiler, depending on which operating system and architecture you are using. The options that are set may change from release to release.
On Linux systems, the -debug inline-debug-info option will be enabled by default if you compile with optimizations (option -O2 or higher) and debugging is enabled (option -g).
Many routines in the shared libraries are more highly optimized for Intel® microprocessors than for non-Intel microprocessors.
For more information on the optimization flags please refer the following links.