[질문] 아파치 모듈 프로파일링 어떤 게 좋을까요?

panda005의 이미지

안녕하세요.

c로 구현한 아파치 모듈을 프로파일링하려면,
어떤 방법이 좋을까요?

아파치 자체를 -pg 옵션주고 컴파일해서 gprof로 보자니 너무 무지막지한 것 같고...
이도 저도 안 되면 그냥 로그파일에 시간기록해서 처리하려구요 ㅠㅠ
좋은 방법 있으면 알려 주세요~

총총~

IsExist의 이미지

Quote:

-finstrument-functions

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

panda005의 이미지

이거 넣고 적용해보면 되겠네요!

panda005의 이미지

-finstrument-functions을 이용해서 등록한
void __cyg_profile_func_enter (void *this_fn, void *call_site);
void __cyg_profile_func_exit (void *this_fn, void *call_site);

이 두 넘과
httpd-2.2.6 모듈 등록할 때, 사용한

ap_hook_handler(hello_handler, NULL, NULL, APR_HOOK_MIDDLE);

이 넘과 후킹 싸움을 하는 것 같은데,
위에 놈이 우선 순위가 밀리네요...
싸워 이기는 좋은 방법이 없을까요?

panda005의 이미지

Makefile


HTTPD_2_2_6_HOME=/work/panda005/httpd-2.2.6
 
CC = gcc
 
TARGETS = mod_hello.so
SOURCES = mod_hello.c profile.c
CFLAGS = -g -finstrument-functions -fPIC
INCLUDES = -I$(HTTPD_2_2_6_HOME)/include
 
OBJECTS = $(SOURCES:.c=.o)
LDFLAGS = -g -finstrument-functions -shared -fPIC
LIBS =
LDADD = -lrt
 
all: $(TARGETS)
 
mod_hello.so: $(OBJECTS)
    $(CC) $(LDFLAGS) $(LIBS) $(LDADD) -o $@ $(OBJECTS)
 
install: all
    cp -pf $(TARGETS) $(HTTPD_2_2_6_HOME)/modules/
 
clean:
    -rm -f core* $(OBJECTS) $(TARGETS)
 
.SUFFIXES: .c
.c.o:
    $(CC) $(CFLAGS) $(INCLUDES) -c $<

profile.c


#include &lt;string.h&gt;
#include &lt;time.h&gt;
#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/types.h&gt;
 
 
void __cyg_profile_func_enter(void *this_fn, void *call_site) __attribute__((no_instrument_function));
void __cyg_profile_func_exit(void *this_fn, void *call_site) __attribute__((no_instrument_function));
 
 
int call_level = 0;
void *last_fn;
 
struct timespec t_start;
clockid_t clock_id;
 
int
f_init ()
{
    int ret;
 
    ret = clock_getcpuclockid (getpid (), &clock_id);
    if (ret < 0)
        return -1;
 
    {
        FILE *fp = fopen ("/tmp/1.log", "a");
        fprintf (fp, "f_init: %d\n", clock_id);
        fclose (fp);
    }
 
    return 0;
}
 
void
__cyg_profile_func_enter (void *this_fn, void *call_site)
{
    if (this_fn != last_fn)
        ++ call_level;
 
    clock_gettime (clock_id, &t_start);
    {
        FILE *fp = fopen ("/tmp/1.log", "a");
        fprintf (fp, "%p[%d]: %lu.%lu start\n", this_fn, call_level, t_start.tv_sec, t_start.tv_nsec);
        fclose (fp);
    }
 
    (void) call_site;
    last_fn = this_fn;
 
    return;
}
 
 
void
__cyg_profile_func_exit (void *this_fn, void *call_site)
{
    struct timespec t_end;
 
    clock_gettime (clock_id, &t_end);
 
    {
        FILE *fp = fopen ("/tmp/1.log", "a");
        fprintf (fp, "%p[%d]: %lu.%lu exit\n", this_fn, call_level, t_end.tv_sec, t_end.tv_nsec);
        fclose (fp);
    }
 
    -- call_level;
 
    (void) call_site;
 
    return;
}

mod_hello.c


#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
 
int
inc (int i)
{
    return ++ i;
}
 
int
dec (int i)
{
    return -- i;
}
 
/* The sample content handler */
int hello_handler(request_rec *r)
{
    f_init ();
 
    if (strcmp(r->handler, "hello")) {
        return DECLINED;
    }
    r->content_type = "text/html";
 
    inc (0);
    dec (0);
    if (!r->header_only)
        ap_rputs("The sample page from mod_hello.c\n", r);
    return OK;
}
 
 
void hello_register_hooks(apr_pool_t *p)
{
    ap_hook_handler (hello_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
 
/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA hello_module = {
    STANDARD20_MODULE_STUFF,
    NULL,                  /* create per-dir    config structures */
    NULL,                  /* merge  per-dir    config structures */
    NULL,                  /* create per-server config structures */
    NULL,                  /* merge  per-server config structures */
    NULL,                  /* table of config file commands       */
    hello_register_hooks  /* register hooks                      */
};

httpd.conf 일부


LoadModule hello_module modules/mod_hello.so
&lt;Location /hello&gt;
    SetHandler  hello
&lt;/Location&gt;
IsExist의 이미지

문제가 instrument_function 함수가 hello_handler()호출 전/후로 호출이
안된다는 거죠?

추측으로는 ap_hook_handler() 함수 호출에서 등록된 함수가 apache가 자동으로 호출해서
컴파일러가 hello_handler() 호출 전/후를 찾기 못해서 instrument_function을
호출하지 않은 것 같습니다. 그에 비해 f_init() 에 대해서는 instrument_function이
호출될 것 같네요.

아파치가 아파치 모듈에서 함수를 호출 하는 방식이 모듈명으로 정의된 데이타
구조체를 호출하고 그 구조체에 정의된 함수 hello_register_hooks()을 호출하는
방식이라 hello_handler() 함수 호출이 컴파일 타임에 결정되는 것이 아니라
실행 결정되어 호출되는 방식이라..

hello_handler() 함수를 한번 더 감싸는 방식으로
호출하게 해보세요.

아래 처럼요.

static int 
real_hello_handler(request_rec *r)
{
    f_init ();
 
    if (strcmp(r->handler, "hello")) {
        return DECLINED;
    }
    r->content_type = "text/html";
 
    inc (0);
    dec (0);
    if (!r->header_only)
        ap_rputs("The sample page from mod_hello.c\n", r);
    return OK;
}
 
/* The sample content handler */
int hello_handler(request_rec *r)
{
    return real_hello_handler(r);
}

참고로 주소값으로 라인정보와 함수정보 변환은 addr2line 명령어를 사용하세요
---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

panda005의 이미지

매번 답해주셔서 감사합니다.

실은 저도 그게 의심되어서,
중간에

f_init ();
...
inc (0);
dec (0);

이걸 넣어서 해본 건데..
f_init, inc, dec 모두 후킹이 안 되네요...

그냥 printf로 시간을 찍을까... 하고 고민중입니다 ㅠㅠ

IsExist의 이미지

Quote:

mn -Ag mod_hello.o |grep __cyg_prof

위 명령어 실행 해보시겠어요. -finstrument-functions 옵션이 안 먹히는건지도..

-finstrument-functions 안되면 print 문으로 해야 겠네요... 에고
---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

panda005의 이미지

../binutils-2.18/binutils/nm-new -Ag mod_hello.o
mod_hello.o: U _GLOBAL_OFFSET_TABLE_
mod_hello.o: U __cyg_profile_func_enter
mod_hello.o: U __cyg_profile_func_exit
mod_hello.o: U ap_hook_handler
mod_hello.o: U ap_rputs
mod_hello.o:0000000000000040 T dec
mod_hello.o: U f_init
mod_hello.o:0000000000000080 T hello_handler
mod_hello.o:0000000000000000 D hello_module
mod_hello.o:0000000000000126 T hello_register_hooks
mod_hello.o:0000000000000000 T inc
mod_hello.o: U strcmp

gcc 3.4.6을 사용중인데,
같은 방법으로 그냥 so 파일 만들어서 할 때는 잘 됐었거든요...
근데 아파치 모듈로 올리니까 말썽이네요 ㅠㅠ
매번 감사해요.
이젠 printf에 의존하는 게... 흑

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.