Mandalika's scratchpad [ Work blog @Oracle | Stock Market Notes | My Music Compositions ]

Old Posts: 09.04  10.04  11.04  12.04  01.05  02.05  03.05  04.05  05.05  06.05  07.05  08.05  09.05  10.05  11.05  12.05  01.06  02.06  03.06  04.06  05.06  06.06  07.06  08.06  09.06  10.06  11.06  12.06  01.07  02.07  03.07  04.07  05.07  06.07  08.07  09.07  10.07  11.07  12.07  01.08  02.08  03.08  04.08  05.08  06.08  07.08  08.08  09.08  10.08  11.08  12.08  01.09  02.09  03.09  04.09  05.09  06.09  07.09  08.09  09.09  10.09  11.09  12.09  01.10  02.10  03.10  04.10  05.10  06.10  07.10  08.10  09.10  10.10  11.10  12.10  01.11  02.11  03.11  04.11  05.11  07.11  08.11  09.11  10.11  11.11  12.11  01.12  02.12  03.12  04.12  05.12  06.12  07.12  08.12  09.12  10.12  11.12  12.12  01.13  02.13  03.13  04.13  05.13  06.13  07.13  08.13  09.13  10.13  11.13  12.13  01.14  02.14  03.14  04.14  05.14  06.14  07.14  09.14  10.14  11.14  12.14 


Tuesday, December 23, 2014
 
Solaris Studio : C/C++ Dynamic Analysis

First, a reminder - Oracle Solaris Studio 12.4 is now generally available. Check the Solaris Studio 12.4 Data Sheet before downloading the software from Oracle Technology Network.

Dynamic Memory Usage Analysis

Code Analyzer tool in Oracle Solaris Studio compiler suite can analyze static data, dynamic memory access data, and code coverage data collected from binaries that were compiled with the C/C++ compilers in Solaris Studio 12.3 or later. Code Analyzer is supported on Solaris and Oracle Enterprise Linux.

Refer to the static code analysis blog entry for a quick summary of steps involved in performing static analysis. The focus of this blog entry is the dynamic portion of the analysis. In this context, dynamic analysis is the evaluation of an application during runtime for memory related errors. Main objective is to find and debug memory management errors -- robustness and security assurance are nice side effects however limited their extent is.

Code Analyzer relies on another primary Solaris Studio tool, discover, to find runtime errors that are often caused by memory mismanagement. discover looks for potential errors such as accessing outside the bounds of the stack or an array, unallocated memory reads and writes, NULL pointer deferences, memory leaks and double frees. Full list of memory management issues analyzed by Code Analyzer/discover is at: Dynamic Memory Access Issues

discover performs the dynamic analysis by instrumenting the code so that it can keep track of memory operations while the binary is running. During runtime, discover monitors the application's use of memory by interposing on standard memory allocation calls such as malloc(), calloc(), memalign(), valloc() and free(). Fatal memory access errors are detected and reported immediately at the instant the incident occurs, so it is easy to correlate the failure with actual source. This behavior helps in detecting and fixing memory management problems in large applications with ease somewhat. However the effectiveness of this kind of analysis highly depends on the flow of control and data during the execution of target code - hence it is important to test the application with variety of test inputs that may maximize code coverage.

High-level steps in using Code Analyzer for Dynamic Analysis

Given the enhancements and incremental improvements in analytical tools, Solaris Studio 12.4 is recommended for this exercise.

  1. Build the application with debug flags

    –g (C) or -g0 (C++) options generate debug information. It enables Code Analyzer to display source code and line number information for errors and warnings.

    • Linux users: specify –xannotate option on compile/link line in addition to -g and other options
  2. Instrument the binary with discover

    % discover -a -H <filename>.%p.html -o <instrumented_binary> <original_binary>

    where:

    • -a : write the error data to binary-name.analyze/dynamic directory for use by Code Analyzer
    • -H : write the analysis report to <filename>.<pid>.html when the instrumented binary was executed. %p expands to the process id of the application. If you prefer the analysis report in a plain text file, use -w <filename>.%p.txt instead
    • -o : write the instrumented binary to <instrumented_binary>

    Check Command-Line Options page for the full list of discover supported options.

  3. Run the instrumented binary

    .. to collect the dynamic memory access data.

    % ./<instrumented_binary> <args>

  4. Finally examine the analysis report for errors and warnings

Example

The following example demonstrates the above steps using Solaris Studio 12.4 C compiler and discover command-line tool. Same code was used to demonstrate static analysis steps as well.

% cat someapp.c
#include <stdio.h>
#include <stdlib.h>

#define SIZE 3

int main() {

        int *arrX[SIZE];

        for (int i = 0; i < SIZE; ++i) {
                arrX[i] = calloc(1, sizeof(int));
                *arrX[i] = (i*5);
        }

        for (int i = 1; i <= SIZE; ++i) {
                printf("\narrX[%d] = %d", i, *arrX[i]);
                free(arrX);
        }

        return 0;
}

% cc -V
cc: Sun C 5.13 SunOS_sparc 2014/10/20

% cc -g -o someapp someapp.c

% discover -a -w dynanalysis.%p.txt -o someapp.dyn someapp
discover: (warning): /var/tmp/someapp: 94.3% of code instrumented (4 out of 5 functions).

% ./someapp.dyn

arrX[1] = 5
arrX[2] = 10Segmentation Fault (core dumped)

% cat dynanalysis.4492.txt
ERROR 1 (BFM): freeing wrong memory block "arrX" at address 0xffbffb00 at:
        main() + 0x214  <someapp.c:17>
                14:
                15:     for (int i = 1; i <= SIZE; ++i) {
                16:             printf("\narrX[%d] = %d", i, *arrX[i]);
                17:=>           free(arrX);
                18:     }
                19:
                20:     return 0;
        _start() + 0x108
ERROR 2 (UMR): accessing uninitialized data at address 0xffbffb0c (4 bytes) on the stack at:
        main() + 0x1c0  <someapp.c:16>
                13:     }
                14:
                15:     for (int i = 1; i <= SIZE; ++i) {
                16:=>           printf("\narrX[%d] = %d", i, *arrX[i]);
                17:             free(arrX);
                18:     }
                19:
        _start() + 0x108
ERROR 3 (IMR): read from invalid memory at address 0x0 (4 bytes)  at:
        main() + 0x200  <someapp.c:16>
                13:     }
                14:
                15:     for (int i = 1; i <= SIZE; ++i) {
                16:=>           printf("\narrX[%d] = %d", i, *arrX[i]);
                17:             free(arrX);
                18:     }
                19:
        _start() + 0x108

Few things to be aware of:

Reference & Recommended Reading:

  1. Oracle Solaris Studio 12.4 : Code Analyzer User's Guide
  2. Oracle Solaris Studio 12.4 : Discover and Uncover User's Guide

Labels:




Saturday, December 20, 2014
 
Economic Effects of Inflation

Read the first part in this series: Inflation

The following are some of the consequences of inflation on a very high level.

Source & References: Various www sources including investopedia, wikipedia, economicshelp.org

Image courtesy: unknown source on www




Friday, November 28, 2014
 
Solaris Studio : C/C++ Static Code Analysis

First things first -- Oracle Solaris Studio 12.4 is now generally available. One of the key features of this release is the support for the latest industry standards including C++11, C11 and OpenMP 4.0. Check the Solaris Studio 12.4 Data Sheet before downloading the software from Oracle Technology Network.

Static Code Analysis

Code Analyzer tool in Oracle Solaris Studio compiler suite can analyze static data, dynamic memory access data, and code coverage data collected from binaries that were compiled with the C/C++ compilers in Solaris Studio 12.3 or later. Code Analyzer is supported on Solaris and Oracle Enterprise Linux.

Primary focus of this blog entry is the static code analysis.

Static code analysis is the process of detecting common programming errors in code during compilation. The static code checking component in Code Analyzer looks for potential errors such as accessing outside the bounds of the array, out of scope variable use, NULL pointer deferences, infinite loops, uninitialized variables, memory leaks and double frees. The following webpage in Solaris Studio 12.4: Code Analyzer User's Guide has the complete list of errors with examples.

    Static Code Issues analyzed by Code Analyzer

High-level steps in using Code Analyzer for Static Code analysis

Given the enhancements and incremental improvements in analysis tools, Solaris Studio 12.4 is recommended for this exercise.

  1. Collect static data

    Compile [all source] and link with –xprevise=yes option.

    • when using Solaris Studio 12.3 compilers, compile with -xanalyze=code option.
    • Linux users: specify –xannotate option on compile/link line in addition to -xprevise=yes|-xanalyze=code.

    During compilation, the C/C++ compiler extracts static errors automatically, and writes the error information to the sub-directory in <binary-name>.analyze directory.

  2. Analyze the static data

    Two options available to analyze and display the errors in a report format.

Example

The following example demonstrates the above steps using Solaris Studio 12.4 C compiler and codean command-line tool.

% cat someapp.c
#include <stdio.h>
#include <stdlib.h>

#define SIZE 3

int main() {

        int *arrX[SIZE];

        for (int i = 0; i < SIZE; ++i) {
                arrX[i] = calloc(1, sizeof(int));
                *arrX[i] = (i*5);
        }

        for (int i = 1; i <= SIZE; ++i) {
                printf("\narrX[%d] = %d", i, *arrX[i]);
                free(arrX);
        }

        return 0;
}

% cc -V
cc: Sun C 5.12 SunOS_sparc Patch 148917-08 2014/09/10

% cc -g -o someapp -xprevise=yes someapp.c

% codean -s someapp
STATIC report of someapp:
ERROR 1 (ABR): reading memory beyond array bounds: arrX[i] at:
        main()  
                12:                     *arrX[i] = (i*5);
                13:             }
                15:             for (int i = 1; i <= SIZE; ++i) {
                16:=>                   printf("\narrX[%d] = %d", i, *arrX[i]);
                17:                     free(arrX);
LEAK 1 : 1 block left allocated on heap with a total size of 1 byte
        main()  
                6:      int main() {
                8:              int *arrX[SIZE];
                10:             for (int i = 0; i < SIZE; ++i) {
                11:=>                   arrX[i] = calloc(1, sizeof(int));
                12:                     *arrX[i] = (i*5);
WARNING 1 (MRC): missing null-pointer check after malloc: calloc(1,4) at:
        main()  
                6:      int main() {
                8:              int *arrX[SIZE];
                10:             for (int i = 0; i < SIZE; ++i) {
                11:=>                   arrX[i] = calloc(1, sizeof(int));
                12:                     *arrX[i] = (i*5);
PREVISE SUMMARY for someapp: 1 error(s), 1 warning(s), 1 leak(s) in total

In addition to displaying plain text output on stdout, codean tool also saves the results in a HTML file in the same directory the executable resides.

% ls someapp*html
someapp.static.html

Few things to be aware of:

Reference & Recommended Reading:
    Oracle Solaris Studio 12.4 Code Analyzer User's Guide

Labels:




Saturday, October 18, 2014
 
Blast from the Past : The Weekend Playlist #7

Previous playlists:

    #1 (50s, 60s and 70s) | #2 (80s) | #3 (80s) | #4 (80s) | #5 (80s) | #6 (90s)

Audio-Visual material courtesy: YouTube. Other information: Wikipedia.

1. Fatboy Slim / Norman Cook - Brimful of Asha (1998)

A remix. Original by UK band Cornershop.

2. Vanilla Ice - Ice Ice Baby (1990)

3. Beck - Loser (1993)

4. Primus - Mr. Krinkle (1993)

5. Tool - Stinkfist (1996)

if you don't mind watching dark videos, look for Stinkfist official video on youtube.

6. P.M. Dawn - Set Adrift On Memory Bliss (1991)

7. Primitive Radio Gods - Standing Outside A Broken Phone Booth (1996)

no traces of official video anywhere on web, for some reason.

8. Blues Traveler - Run-Around (1995)

Grammy winner.

9. KoRn - A.D.I.D.A.S. (1997)

Under Pressure mix. Another dark song that has nothing to do with sportswear brand, Adidas.

10. Chumbawamba - Tubthumping (1997)

one hit wonder.

Labels:




Tuesday, September 30, 2014
 
Programming in C: Few Tidbits #3

1) Not able to redirect the stdout output from a C program/application to a file

Possible cause:

Buffered nature of standard output (stdout) stream. Might be waiting for a newline character, for the buffer to be full, or for some other condition to be met based on implementation.

Few potential workarounds:


2) Printing ("escaping" maybe?) a percent sign (%) in a printf formatted string

Conversion/format specifiers start with a % sign, and using the slash sequence to escape the % sign in strings that are not format specifiers usually does not work. Check the following example out.

eg.,

Executing the following code:

        int pct = 35;
        printf("\n%d%", pct);

.. results in:

35, but not 35% as one would expect.

Format specifier "%%" simply prints the percent sign - so, the desired result can be achieved by replacing "%d%" with "%d%%" in printf statement.

        int pct = 35;
        printf("\n%d%%", pct);

.. shows:

35% as expected

(web search keywords: C printf conversion specification)


3) Duplicating a structure

If the structure has no pointers, assigning one struct to another struct duplicates the structure. The same effect can be achieved by using memcpy() too, but it is not really necessary. After the execution of struct assignment, there will be two copies of struct with no dependency - so, they can be operated independently without impacting the other. The following sample code illustrates this point.

eg., #1
 ...
 ...

 typedef struct human {
  int accno;
         int age;
 } person;

 ...
 ...

 person guy1, guy2;

 guy1.accno = 20202;
 guy1.age = 10;

 guy2 = guy1;

 printf("\nAddress of:\n\t-> guy1: %p. guy2: %p", guy1, guy2);

 printf("\n\nBefore update:\n");
 printf("\naccno of:\n\t-> guy1: %d. guy2: %d", guy1.accno, guy2.accno);
 printf("\nage of:\n\t-> guy1: %d. guy2: %d", guy1.age, guy2.age);

 guy1.age = 15;
 guy2.accno = 30303;

 printf("\n\nAfter update:\n");
 printf("\naccno of:\n\t-> guy1: %d. guy2: %d", guy1.accno, guy2.accno);
 printf("\nage of:\n\t-> guy1: %d. guy2: %d", guy1.age, guy2.age);

 ...
 ...
 

Execution outcome:

Address of:
        -> guy1: ffbffc38. guy2: ffbffc30

Before update:

accno of:
        -> guy1: 20202. guy2: 20202
age of:
        -> guy1: 10. guy2: 10

After update:

accno of:
        -> guy1: 20202. guy2: 30303
age of:
        -> guy1: 15. guy2: 10

On the other hand, if the structure has pointer variable(s), duplication of a structure using assignment operator leads to pointer variables in both original and copied structures pointing to the same block of memory - thus creating a dependency that could potentially impact both pointer variables with unintended consequences. The following sample code illustrates this.

eg., #2
 ...
 ...

 typedef struct human {
         int *accno;
         int age;
 } person;

 ...
 ...

 person guy1, guy2;

 guy1.accno = malloc(sizeof(int));
 *(guy1.accno) = 20202;

 guy1.age = 10;
 guy2 = guy1;
 
 ...
 ...

 guy1.age = 15;
 *(guy2.accno) = 30303;

 ...
 ...
Execution outcome:
Address of:
        -> guy1: ffbffb48. guy2: ffbffb40

Before update:

accno of:
        -> guy1: 20202. guy2: 20202
age of:
        -> guy1: 10. guy2: 10

After update:

accno of:
        -> guy1: 30303. guy2: 30303
age of:
        -> guy1: 15. guy2: 10

Few people seem to refer this kind of duplication as shallow copy though not everyone agrees with the terminology.

If the idea is to clone an existing struct variable that has one or more pointer variables, then to work independently on the clone without impacting the struct variable it was cloned from, one has to allocate memory manually for pointer variables and copy data from source structure to the destination. The following sample code illustrates this.

eg., #3
 ...
 ...

 typedef struct human {
         int *accno;
         int age;
 } person;

 ...
 ...

 person guy1, guy2;

 guy1.accno = malloc(sizeof(int));
 *(guy1.accno) = 20202;

 guy1.age = 10;

 guy2.age = guy1.age;
 guy2.accno = malloc(sizeof(int));
 *(guy2.accno) = *(guy1.accno);

 ...
 ...

 guy1.age = 15;
 *(guy2.accno) = 30303;

 ...
 ...

Execution outcome:

Address of:
        -> guy1: ffbffaa8. guy2: ffbffaa0

Before update:

accno of:
        -> guy1: 20202. guy2: 20202
age of:
        -> guy1: 10. guy2: 10

After update:

accno of:
        -> guy1: 20202. guy2: 30303
age of:
        -> guy1: 15. guy2: 10

This style of explicit duplication is referred as deep copy by few people though not everyone agrees with the terminology.





2004-2015 

This page is powered by Blogger. Isn't yours?