2016-12-28 6 views
2

FIO는 IO 엔진의 전체 무리를 지원 - 모든 엔진은 여기에 존재 지원 : 나는 어떻게 FIO 작품의 내부를 이해하기 위해 노력 해왔다 방법 FIO 부하 모든 IO 엔진에 붙어있어 https://github.com/axboe/fio/tree/master/engines시작시 다양한 io 엔진을로드하는 방법은 무엇입니까?

. https://github.com/axboe/fio/blob/master/engines/sync.c#L448

fio_syncio_unregister : https://github.com/axboe/fio/blob/master/engines/sync.c#L461

I 모든 엔진을 참조 예

다음 방법

fio_syncio_register을 사용하여 실시 예 sync.c 등록 및 등록 취소에 대한 등록 및 등록을 취소하는 방법이있다

내 질문에 누가이 방법을 부르는거야?

내가 GDB에서 FIO 실행 시도 답을 찾으려면 - fio_syncio_register에 브레이크 포인트를 배치하고 주요 기능에, fio_syncio_register 심지어는 확인 __libc_csu_init 및 역 추적을 함께 할 수있는 뭔가가 저를 알려줍니다 주 전에 불려 가도록

(gdb) bt 
#0 fio_syncio_register() at engines/sync.c:450 
#1 0x000000000047fb9d in __libc_csu_init() 
#2 0x00007ffff6ee27bf in __libc_start_main (main=0x40cd90 <main>, argc=2, argv=0x7fffffffe608, init=0x47fb50 <__libc_csu_init>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe5f8) 
    at ../csu/libc-start.c:247 
#3 0x000000000040ce79 in _start() 

나는 언젠가에 대한 __libc_csu_init__libc_csu_fini__attribute__((constructor))로 장식 된 방법에 대한 하나 하나 설명 회담을 읽는 데 소요하는 것은 주 전에 호출되지만, FIO sync.c의 경우 나는 fio_syncio_register __attribute__

장식을 참조하십시오 해달라고

누군가이 흐름이 어떻게 작동하는지 이해할 수 있도록 도와 줄 수 있습니까? 이것을 이해하기 위해 읽어야 할 다른 자료가 있습니까?

감사합니다.

답변

0

흥미로운 질문입니다. 나는 소스보고 답을 알아낼 수 없게되고 여기에 내가 찍은 단계는 다음과 같습니다이 글로벌 이니셜이 객체에 존재하는 것을 우리에게 알려줍니다

$ make 
$ find . -name 'sync.o' 
./engines/sync.o 

$ readelf -WS engines/sync.o | grep '\.init' 
    [12] .init_array  INIT_ARRAY  0000000000000000 0021f0 000008 00 WA 0 0 8 
    [13] .rela.init_array RELA   0000000000000000 0132a0 000018 18  36 12 8 

은. 이들은 프로그램 시작시 호출됩니다. 그들은 무엇인가?

$ objdump -Dr engines/sync.o | grep -A4 '\.init' 
Disassembly of section .init_array: 

0000000000000000 <.init_array>: 
    ... 
      0: R_X86_64_64 .text.startup 

흥미 롭습니다. 분명히 특별한 .text.startup 섹션이 있습니다. 그거 안에 뭐가 있나요?

$ objdump -dr engines/sync.o | less 
... 
Disassembly of section .text.startup: 

0000000000000000 <fio_syncio_register>: 
    0: 48 83 ec 08    sub $0x8,%rsp 
    4: bf 00 00 00 00   mov $0x0,%edi 
         5: R_X86_64_32 .data+0x380 
    9: e8 00 00 00 00   callq e <fio_syncio_register+0xe> 
         a: R_X86_64_PC32  register_ioengine-0x4 
... 

왜 우리가 찾고있는 기능입니까? 그러나이 특별한 섹션에서 어떻게 끝났습니까? 그 대답을 위해 전처리 된 소스를 살펴볼 수 있습니다 (회상시 으로 시작해야 함).

어떻게 얻을 수 있습니까? sync.o을 컴파일하는 명령 줄은 숨겨져 있습니다. Makefile을 보면 QUIET_CC=''으로 명령 줄을 숨김 해제 할 수 있습니다.

$ rm engines/sync.o && make QUIET_CC='' 
gcc -o engines/sync.o -std=gnu99 -Wwrite-strings -Wall -Wdeclaration-after-statement -g -ffast-math -D_GNU_SOURCE -include config-host.h -I. -I. -O3 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -DBITS_PER_LONG=64 -DFIO_VERSION='"fio-2.16-5-g915ca"' -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DFIO_INTERNAL -DFIO_INC_DEBUG -c engines/sync.c 
    LINK fio 

이제 우리는 명령 줄을 알고, 전처리 파일을 생성 할 수 있습니다 :

$ gcc -E -dD -std=gnu99 -ffast-math -D_GNU_SOURCE -include config-host.h -I. -I. -O3 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -DBITS_PER_LONG=64 -DFIO_VERSION='"fio-2.16-5-g915ca"' -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DFIO_INTERNAL -DFIO_INC_DEBUG engines/sync.c -o /tmp/sync.i 

/tmp/sync.i에서 상대를, 우리는 다음을 참조하십시오

static void __attribute__((constructor)) fio_syncio_register(void) 
{ 
register_ioengine(&ioengine_rw); 
register_ioengine(&ioengine_prw); 
... 

흠, 그것은 __attribute__((constructor)) 모든 후 . 그러나 어떻게 거기에 갔습니까? 아하!

static void fio_init fio_syncio_register(void) 

무엇을 위해 fio_init 서 않습니다 나는 this linefio_init을 놓친? 다시 /tmp/sync.i에서 : 어떻게 작동하는지이

#define fio_init __attribute__((constructor)) 

그래서 있다.

+0

와우 나는 이것을 결코 이해하지 못했을 것입니다.이 노력에 대해 대단히 감사합니다. – nachiappan