Drew Dormann
Drew Dormann

Reputation: 63946

Detect if C++ binary is optimized

Is there a flag or other reliable method to detect if a compiled C++ binary was compiled with optimizations?

I'm okay with compiler-specific solutions.


Edit: This is for a build deployment system, which could accidentally deploy binaries that were not built properly. A water-tight solution is unlikely, but it will save some pain (and money) if this can be detected some of the time.

The compiler will often be gcc, sometimes sun, and if there's a MSVC solution, I don't want to rule that out for the benefit of the community.

Upvotes: 10

Views: 7878

Answers (10)

Suma
Suma

Reputation: 34443

Possible Heuristics Solution

If I would be given this task and it would prove it is a reasonable task (see below), I would perform "a frequency analysis" of the patterns seen in the executable disassembly. As a programmer I am able to distinguish between an optimized and an unoptimized (debug) code at a first glance. I would try to formalize the decision process, with Visual Studio and the x86 platform the typical features seen in an unoptimized exe would be:

  • functions with full prologue/epilogue (ebp based stack frames)
  • a lot of mov-s from/into memory (all variables placed in the memory)

This is definitely not 100 %, but with longer exe I would expect the results to be quite reliable.

I assume for other x86 platforms including GCC the rules will be similar, if not the same, and for other platforms similar rules can be found.

Other heuristics like detection of the runtime library may work as well, depending on compiler settings.

Task sounds silly

That said, I think such task "smells" and under most circumstances it would be sensible to avoid it completely. If you will provide the real reason behind such task, it is very likely some sensible solution will be found.

Upvotes: 8

Indy9000
Indy9000

Reputation: 8881

On Windows you could check if the debug info is stripped from the binary. If you examine the binary image for COFF header, there's a 2 byte flag block called Characteristics at byte offset 18 from COFF header. If the flag

 IMAGE_FILE_DEBUG_STRIPPED = 0x0200

is set then the debugging information is removed from the image file.

This could be done with a trivial 2 byte read from file offset 0x52 and checking if the flag is set.

Flag could be checked as follows

 short flag_block;

 FILE * p_image_file = fopen (...); 

 fseek(p_image_file,0x52,SEEK_SET);

 fread(&flag_block,2,1,p_image_file);

 if(flag_block & 0x0200 > 0)
    then debug info is stripped

You could find the Windows PE format document from Microsoft which describes it in more detail for you to calculate the byte offset to read from etc...

Upvotes: 4

Max Lybbert
Max Lybbert

Reputation: 20047

Recent versions of GCC have a way to report which flags were used to compile a binary (third bullet point).

There is a related command line switch (--fverbose-asm) that "only records the information in the assembler output file as comments, so the information never reaches the object file." The --frecord-gcc-switches switch "causes the command line that was used to invoke the compiler to be recorded into the object file that is being created."

Upvotes: 12

Crashworks
Crashworks

Reputation: 41482

The technique we use is simply to create a symbol that appears in every library only if built debug:

// included_by_everything.h
#ifdef (_DEBUG)
extern "C" __declspec( dllexport ) void WasBuiltInDebug() {}
#else
// nothing!
#endif

And then when loading each module at runtime (or in a Perforce trigger) we can ask the binary if it's debug by simply looking for that symbol:

bool IsDebugDLL( HMODULE DllHandle )
{
  // this system call returns a nonzero address if it can 
  // find the symbol, and NULL otherwise:
  return GetProcAddress( DllHandle , "WasBuiltInDebug" );
}

Upvotes: 8

Nick
Nick

Reputation: 7760

Perhaps you could use a different indicator to determine if you're deploying the right binary. e.g.

  • Debug info: Maybe your release binaries differ in that they dont have debug info? You could check this with elfdump or gdb.
  • Stripped: If your release binaries are stripped you could use "file" to check this

Upvotes: 0

Captain Segfault
Captain Segfault

Reputation: 1726

I'd be surprised if you're not already doing something like this, but:

If you "trust" the build system, put the options used to build into a string you can extract from a running program. (ie, from --version or an about dialog)

This won't detect problems with non-optimized object files getting into the build due to a broken build system, but it will let you easily differentiate a developer build from a release build.

Your release process can then include checking the version to make sure it isn't debug/nonoptimized.

Upvotes: 2

artificialidiot
artificialidiot

Reputation: 5379

In my experience, only reliable way is to examine disassembly itself if you don't know the compiler. First try to dump all strings with your favorite tool and look for clues in the linked library names and exported symbols. Failing that, look for common instruction sequences which are mostly get thrown away after optimizations like stack frame prologue and orderly and easy to understand register usage. If tools like ollydbg get confused about where a function starts and ends, there is a good chance binary is compiled with optimizations on.

Examining a decompiler's output may also help. Last time I checked, they were no better than a disassembler but things may have improved since then.

Upvotes: 2

Mark Ransom
Mark Ransom

Reputation: 308520

For Microsoft C++, you may be able to assume that optimization was turned off if the executable is referencing the debug versions of the run-time DLLs. It's not a guarantee, though.

Upvotes: 3

anon
anon

Reputation:

You don't mention a specific platform, so the answer might be yes. But for most common platforms, the answer is no.


Upvotes: 3

Goz
Goz

Reputation: 62333

I'm pretty sure there is no way. Unless you have specific knowledge of a function inside that you can check to see if the code sequence is optimal or not.

Upvotes: 1

Related Questions