'no_instrument_function'에 해당되는 글 1건

  1. 2013.08.28 GCC, instrument function
카테고리 없음2013. 8. 28. 16:15




/*
	test.c

	2013. 8. 28.
*/
#include <stdio.h>
#include <stdlib.h>


__attribute__ ((no_instrument_function))
void __cyg_profile_func_enter(void *this, void *callsite)
{
	printf ("__cyg_profile_func_enter\n");
}

__attribute__ ((no_instrument_function))
void __cyg_profile_func_exit(void *this, void *callsite)
{
	printf ("__cyg_profile_func_exit\n");
}

__attribute__ ((constructor))
void myConstructor( void )
{
	printf ("constructor\n");
}

__attribute__ ((destructor))
void myDestructor( void )
{
	printf ("destuctor!\n");
}


void func_a( void )
{
	printf ("func_a\n");
	return;
}

__attribute__ ((no_instrument_function))
void func_b( void )
{
	printf ("func_b\n");
	return;
}


int main()
{
	printf ("main\n");
	func_a();
	func_b();

	return 0;
}


constructor, destructor는 생략해도 된다.

결과는,


dqxt@dons-pleiades ~/study/kernel/instrument_fn $ gcc -o test -finstrument-functions test.c 
dqxt@dons-pleiades ~/study/kernel/instrument_fn $ ./test
__cyg_profile_func_enter
constructor
__cyg_profile_func_exit
__cyg_profile_func_enter
main
__cyg_profile_func_enter
func_a
__cyg_profile_func_exit
func_b
__cyg_profile_func_exit
__cyg_profile_func_enter
destuctor!
__cyg_profile_func_exit
dqxt@dons-pleiades ~/study/kernel/instrument_fn $ 


또 다른 예제.



/*
	test2.c

	2013. 8. 28.
*/

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


static FILE *fp_trace;

__attribute__ ((constructor))
void trace_begin (void)
{
	printf ("constructor.\n");
	fp_trace = fopen("trace.out", "w");
}

__attribute__ ((destructor))
void trace_end (void)
{
	printf ("destructor.\n");
	if (fp_trace != NULL) {
		fclose(fp_trace);
	}
}

__attribute__ ((no_instrument_function))
void __cyg_profile_func_enter (void *func,  void *caller)
{
	printf ("__cyg_profile_func_enter.\n");
	if (fp_trace != NULL) {
		fprintf(fp_trace, "e %p %p %lu\n", func, caller, time(NULL) );
	}
}


__attribute__ ((no_instrument_function))
void __cyg_profile_func_exit (void *func, void *caller)
{
	printf ("__cyg_profile_func_exit.\n");
	if(fp_trace != NULL) {
		fprintf(fp_trace, "x %p %p %lu\n", func, caller, time(NULL));
	}
}

void func_a( void )
{
	printf ("in function_a.\n");
	return;
}

__attribute__ ((no_instrument_function))
void func_b( void )
{
	printf ("in function_b.\n");
	return;
}

int main()
{
	printf ("in main.\n");
	func_a();
	func_b();

	return 0;
}


결과는,


dqxt@dons-pleiades ~/study/kernel/instrument_fn $ gcc -o test2 -finstrument-functions test2.c 
dqxt@dons-pleiades ~/study/kernel/instrument_fn $ ./test2
__cyg_profile_func_enter.
constructor.
__cyg_profile_func_exit.
__cyg_profile_func_enter.
in main.
__cyg_profile_func_enter.
in function_a.
__cyg_profile_func_exit.
in function_b.
__cyg_profile_func_exit.
__cyg_profile_func_enter.
destructor.
__cyg_profile_func_exit.
dqxt@dons-pleiades ~/study/kernel/instrument_fn $ ./readtracelog.sh test2 trace.out 
Exit  trace_begin at 2013-08-28T16:12:39+0900
Enter main at 2013-08-28T16:12:39+0900, called from ?? (??:0)
Enter func_a at 2013-08-28T16:12:39+0900, called from main (??:?)
Exit  func_a at 2013-08-28T16:12:39+0900
Exit  main at 2013-08-28T16:12:39+0900
Enter trace_end at 2013-08-28T16:12:39+0900, called from ?? (??:0)
dqxt@dons-pleiades ~/study/kernel/instrument_fn $ 


readtracelog.sh의 내용은,



#!/bin/sh
if test ! -f "$1"
then
	echo "Error: executable $1 does not exist."
	exit 1
fi

if test ! -f "$2"
then
	echo "Error: trace log $2 does not exist."
	exit 1
fi

EXECUTABLE="$1"
TRACELOG="$2"

while read LINETYPE FADDR CADDR CTIME; do
	FNAME="$(addr2line -f -e ${EXECUTABLE} ${FADDR}|head -1)"
	CDATE="$(date -Iseconds -d @${CTIME})"

	if test "${LINETYPE}" = "e"
	then
		CNAME="$(addr2line -f -e ${EXECUTABLE} ${CADDR}|head -1)"
		CLINE="$(addr2line -s -e ${EXECUTABLE} ${CADDR})"
		echo "Enter ${FNAME} at ${CDATE}, called from ${CNAME} (${CLINE})"
	fi

	if test "${LINETYPE}" = "x"
	then
		echo "Exit  ${FNAME} at ${CDATE}"
	fi

done < "${TRACELOG}"



Posted by 쿨한넘