Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

593
557
422264


[부록 A] GCC 지시어: noinline 부록

noinline 키워드로 함수를 선언하면 GCC 컴파일러는 이 함수를 인라인으로 처리하지 않습니다.  
이해를 돕기 위해 예제 코드를 소개합니다.

https://elixir.bootlin.com/linux/v4.19.30/source/mm/slub.c 
static noinline int alloc_debug_processing(struct kmem_cache *s,
struct page *page,
void *object, unsigned long addr)
{
if (s->flags & SLAB_CONSISTENCY_CHECKS) {
if (!alloc_consistency_checks(s, page, object, addr))
goto bad;
}

alloc_debug_processing() 함수 키워드로 noinline을 지정했습니다. 참고로  alloc_debug_processing() 함수는 슬럽 오브젝트를 할당할 때 '오브젝트 오염을 점검하는 역할을 수행합니다.

그런데 GCC는 컴파일 과정에서 inline 키워드로 함수를 선언하지 않아도 '인라인으로 처리해도 적합한 함수'라고 판단하면 다음과 같이 처리 합니다. 

    함수를 인라인 타입으로 컴파일을 합니다.
   
물론 GCC 컴파일러가 알아서 인라인으로 함수를 처리해주니 고맙단 생각이 들 수 있습니다. 하지만 문제는 코드를 작성한 의도와 다르게 함수가 오동작할 수 있다는 점입니다.

한 가지 예를 들어볼까요? 어떤 개발자가 __builtin_return_address() 매크로 함수를 써서 자신을 호출한 함수 주소에 따라 다른 처리를 하려 합니다.

그런데 만약 해당 함수가 인라인으로 처리되면 어떻게 처리될까요? 해당 함수가 인라인으로 처리가 되니 함수 주소나 심볼이 사라지게 됩니다. 따라서  __builtin_return_address() 매크로는 다른 결과를 반환합니다. 예상치 못한 동작을 하게 됩니다.


필자가 개발 도중 예전에 도저히 설명이 불가능한 문제를 만난 적이 있습니다.
수 많은 시행착오 끝에 알아낸 근본 원인이 'GCC가 자동으로 인라인으로 함수를 처리' 했다고 밝혀진 적이 있습니다.

"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!" 

Thanks,
Austin Kim(austindh.kim@gmail.com)


[부록 A] GCC 지시어
   * inline    
   * noinline    
   * __noreturn   
   * unused   
[부록 B] 리눅스 커널 실력을 키우는 방법
[부록 C] 리눅스 커널 프로젝트에 기여하기  
C.1 리눅스 커널 오픈소스 프로젝트 소개 
   * 용어  
C.2 설정 방법 
C.3 패치 코드를 작성한 후 이메일로 보내기  
C.5 리눅스 커널 오픈소스 프로젝트로 얻는 지식 


# Reference: For more information on 'Linux Kernel';

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 1

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 2


 



핑백

덧글

댓글 입력 영역