Friday, 6 April 2018

How to use gprof to generate gmon.out while running the program

How to use gprof to generate gmon.out while running the program

  • The function "monstartup" is used to reinitialize the data block used by gmon to collect profile data.
  • The function "_mcleanup"  writes profile data to gmon.out
  • Change the current direct to /tmp to place the gmon.out to the default folder /tmop
  • After finish the test revert the current folder.
  • Send the SIGUSR2  signal to the process to generate the gmon.out file.
  • Generate the gmon.out file
    • send the signal using below
      • $kill -s SIGUSR2 26908
  • See the output in below folder
    • $cd /tmp

Example Program:

Program file 1: gprof_test-signal.c

#include<stdio.h>
#include<stdlib.h>


#include <dirent.h>
#include <sys/gmon.h>
#include <signal.h>
#include <string.h>

void write_gmon_out_file();
void sigusr2_handler(int sig);
void gprof_init(void);

/* Beginning and end of our code segment.  */
extern void _start (void), etext (void);

/*
 * This function uses APIs from the gmon library which is part of the
 * the standard glibC library, to force write the profile data.
 * The function "monstartup" is used to reinitialize the data block
 * used by gmon to collect profile data.
 * The function "_mcleanup"  writes profile data to gmon.out
 */
void write_gmon_out_file (void)
{
    char *gmon_dir = "/tmp";
    char originalDir[256];

    if (getcwd(originalDir, 256) == '\0') {
        printf("Failed to get original working directory... \n");
        memset(originalDir, 0, 256);
    }
    else {
        printf("Original Dir = %s \n", originalDir);
    }

    if (chdir(gmon_dir) == 0) {
        printf("Successfully changed to dir = %s \n", gmon_dir);
    }
    else {
        printf("Failed to change to dir = %s \n", gmon_dir);
    }

    _mcleanup();
    monstartup((unsigned long ) &_start, (unsigned long ) &etext);

    if (originalDir[0] != 0) {
        printf("Switching to original working dir ...\n");
        chdir(originalDir);
    }

    return ;
}

void sigusr2_handler(int sig)
{
    printf("Received Signal: %d\n", sig);
    write_gmon_out_file() ;
    signal(SIGUSR2, sigusr2_handler) ;
}
void gprof_init(void)
{
    signal(SIGUSR2, sigusr2_handler) ;
    printf("GPROF SIGNAL HANDLER INITIALIZED\r\n");
    sleep(5);
}
void new_func1(void);

void func1(void)
{
    printf("\n Inside func1 \n");
    int i = 0;

    //exit(0);
    sleep(10);
    for(;i<0xffffffff;i++);
    new_func1();

    return;
}

static void func2(void)
{
    printf("\n Inside func2 \n");
    int i = 0;

    for(;i<0xffffffaa;i++);
    return;
}

int main(void)
{
    printf("\n Inside main()\n");
    int i = 0;

     gprof_init();
    for(;i<0xffffff;i++);
    func1();
    func2();

    return 0;
}

Program 2: gprof_test_2.c

//test_gprof_new.c
#include<stdio.h>

void new_func1(void)
{
    printf("\n Inside new_func1()\n");
    int i = 0;

    for(;i<0xffffffee;i++);

    return;
}

Output:

Execute the program:
gprof$ ./a.out

 Inside main()
GPROF SIGNAL HANDLER INITIALIZED

 Inside func1

Received Signal: 12
Original Dir = /home/labuser/velrajk/sample/gprof
Successfully changed to dir = /tmp
Switching to original working dir ...

---- output file.
$cd /tmp
$ ls gmon.out 
gmon.out
$

No comments:

Post a Comment