Profiling

Profiling

For those using gprof and CXXFLAGS += -pg, you can generate to generate profiling data by (1) running cryptest.exe v to run the library's self tests; or (2) run cryptest.exe b to use the built in bench-marking suite.

> cryptest.exe b > benchmark.html   # gmon.out written in PWD by instrumentation
> gprof -a -b cryptest.exe gmon.out > cryptest.exe.prof
> cat cryptest.exe.prof | more      # output below is baked for screen formatting
Flat profile:

Each sample counts as 0.01 seconds.
%   cumulative   self              self     total
time   seconds   seconds    calls   s/call   s/call  name
15.68     16.16    16.16  9325567     0.00     0.00  CryptoPP::Rijndael::Enc::AdvancedProcessBlocks
5.97     22.31     6.15  1094386     0.00     0.00  CryptoPP::GF2NT::Multiply
4.50     26.95     4.64   559773     0.00     0.00  CryptoPP::AlmostInverse
3.73     30.79     3.84   547193     0.00     0.00  CryptoPP::GF2NT::MultiplicativeInverse
2.54     33.41     2.62  1048576     0.00     0.00  CryptoPP::Salsa20_Policy::OperateKeystream
2.50     35.99     2.58   320517     0.00     0.00  CryptoPP::RawDES::RawSetKey
2.27     38.33     2.34   655360     0.00     0.00  CryptoPP::GCM_Base::AuthenticateBlocks
...

Memory Leaks

The Crypto++ mailing list occasionally receives messages concerning memory leaks from tools such as Purify and Bounds Checker. Under most circumstances, Crypto++ is leak free and the problem stems from one of two places - a legitimate leak (in the program using the library and not the library itself) and a false positive.

Reported Leak

The first leak is due to the programmer and is a valid item. The allocation occurs in the user's program but when the dump is printed, there is so much Crypto++ library code in the chain a programmer mistakenly claims the leak is with the library.

If you feel the library is truly leaking, please file a Bug Report. Before reporting, you should run cryptest v under the tool as a base case.

False Positive

The second leak is a false positive due to a tool reporting a leak where there is no leak. For example, in the past, BoundsChecker would report a C++ library object leaked even though the object was reclaimed during C++ library shutdown when the static destructors executed. The problem was that the BoundsChecker DLL was unloaded before the runtime library terminated.

In the Microsoft environment, Visual Studio will report a leak when using Run-Time Type Information (RTTI). Microsoft states the warning can be safely ignored in KB140670. Below is a typical example of the typeid() leak. Notice that the output occurs in pairs (for example, allocations 1336110 and 1336111).

Detected memory leaks!
Dumping objects ->
{1336111} normal block at 0x003AECA8, 30 bytes long.
Data: <class CryptoPP::> 63 6C 61 73 73 20 43 72 79 70 74 6F 50 50 3A 3A
{1336110} normal block at 0x003ABB28, 8 bytes long.
Data: <  : X   > A8 EC 3A 00 58 06 AB 00
{798888} normal block at 0x003AB918, 58 bytes long.
Data: <class CryptoPP::> 63 6C 61 73 73 20 43 72 79 70 74 6F 50 50 3A 3A
{798887} normal block at 0x00AB0658, 8 bytes long.
Data: <  :   : > 18 B9 3A 00 B8 B9 3A 00


Though the issue has been well know since Visual C++ 4.0 days, it does not appear that Microsoft will fix the false positive. See Memory leaks reported by debug CRT inside typeinfo.name().

Validating Library Memory Usage

After building the Crypto++ library, it is usually a good idea to verify the build with cryptest v. Claiming validation is a good idea is an understatement - the build must be validated. Validation is a perfect time to run other tools, such as Purify and Valgrind, against the executable.

$./cryptest.exe V 5.6.1$ ./cryptest.exe v
Using seed: 1282115289

Testing Settings...

passed:  Your machine is little endian.
passed:  Your machine allows unaligned data access.
passed:  sizeof(byte) == 1
passed:  sizeof(word16) == 2
passed:  sizeof(word32) == 4
passed:  sizeof(word64) == 8
passed:  sizeof(word128) == 16
passed:  sizeof(hword) == 4, sizeof(word) == 8, sizeof(dword) == 16
passed:  hasMMX == 1, hasISSE == 1, hasSSE2 == 1, hasSSSE3 == 1, hasAESNI == 0, hasCLMUL == 0, isP4 == 0, cacheLineSize == 64, AESNI_INTRINSICS == 1

...

All tests passed!

Test ended at Wed Aug 18 03:08:10 2010
Seed used was: 1282115289

Uninitialized Memory

Random pools can use unintialized memory as a source of entropy. Before filing a report, please verify the usage is not related to a random source. Also see Vendors are Bad for Security.

Application Verifier

Application Verifier is a Microsoft tool which profiles an application. To use Application Verifier, add cryptest.exe to the application list. Then run cryptest v under the Visual Studio debugger.

Below is a run with Memory, Heaps, Dangerous APIs, and Dirty Stacks enabled. Dangerous APIs include original C runtime functions such as memcpy (we should now use memcpy_s). Dirty Stacks checks for the use of uninitialized variables. The log file is not shown since there are 0 errors and 0 warnings.

Valgrind and Valkyrie

To validate with Valgrind, perform the following from the build directory. The build directory is required so that the Test Vectors are available during the self test.

cd cryptopp-5.6.0/
valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./cryptest.exe v


After a successful run, output should be similar to below. If new to Valgrind, 17992 is the process id of the test run.

==17992== Memcheck, a memory error detector.
==17992== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==17992== Using LibVEX rev 1884, a library for dynamic binary translation.
==17992== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==17992== Using valgrind-3.4.1, a dynamic binary instrumentation framework.
==17992== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==17992== For more details, rerun with: -v
==17992==
...
==17992==
==17992== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 5 from 1)
==17992== malloc/free: in use at exit: 0 bytes in 0 blocks.
==17992== malloc/free: 1,119,117 allocs, 1,119,117 frees, 60,533,882 bytes allocated.
==17992== For counts of detected errors, rerun with: -v
==17992== All heap blocks were freed -- no leaks are possible.


OS X

You might experience a memory leak under OS X. This is likely a known issue due to Apple's use of localtime. Also see How to resolve dyld and localtime leaks when profiling a project? and Valgrind memory leak points to localtime on Stack Overflow.

==33810== LEAK SUMMARY:
==33810==    definitely lost: 2,081 bytes in 3 blocks
==33810==    indirectly lost: 1,040 bytes in 1 blocks
==33810==      possibly lost: 10,808 bytes in 1 blocks
==33810==    still reachable: 20,714 bytes in 10 blocks
==33810==         suppressed: 58,630 bytes in 350 blocks
==33810== Rerun with --leak-check=full to see details of leaked memory

Valkyrie

Valkyrie is a visual front end to Valgrind. Below is a typical run of cryptest using the Crypto++ test vectors.