Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

67112
549
416207


[공유][문의] line 19: echo: write error: Invalid argument라는 에러가 뜹니다 Question_Announcement

아래와 같이 독자분께서 블로그에 댓글로 문의를 주셨는데, 답신 내용이 길어져 아예 새롭게 포스팅을 합니다.

링크


문의) 

커널빌드하고 설치한후 irq_trace_ftrace.sh를 실행하면 line 19: echo: write error: Invalid argument라는 에러가 뜹니다. 오타가 있었나 찾아보기도 하고 proc.c 함수명이 틀렸나하고 봐도 이상한게 없는데 뭐가 문제일지 알수 있을까요? 제가 쓴 스크립트 아래와 같이 올려봅니다.

echo rpi_get_interrupt_info bcm2835_mmc_irq > /sys/kernel/debug/tracing/set_ftrace_filter

답변)

1. available_filter_functions을 확인해보세요.

'/sys/kernel/debug/tracing/set_ftrace_filter' 파일에 지정할 수 있는 함수 이름은 아래 파일에 있어야 합니다.

'/sys/kernel/debug/trace/available_filter_functions'

이 블로그 글에 첨부한 'available_filter_functions' 파일(available_filter_functions.txt)을 보시면 다음과 같이 rpi_get_interrupt_info, bcm2835_mmc_irq 함수 이름이 보일 겁니다.
...
init_irq_proc
rpi_get_interrupt_info //<<-- 함수 이름
show_interrupts
...
bcm2835_mmc_finish_command
bcm2835_mmc_irq  //<<-- 함수 이름
bcm2835_mmc_set_clock

먼저 지금 사용 중인 라즈베리 파이에서 '/sys/kernel/debug/trace/available_filter_functions' 파일을 여시고,
위에서 언급한 함수가 있는 지 확인해주세요.

available_filter_functions 파일에 'rpi_get_interrupt_info' 함수 이름이 보이지 않으면, rpi_get_interrupt_info() 함수가 제대로 라즈베리 파이에 설치가 되지 않는 것입니다.

기존 코드 대신에,
아래 구문을 입력해보시면 어느 함수를 필터로 지정하다가 문제가 생겼는지 확인할 수 있습니다.

(기존 코드)
echo rpi_get_interrupt_info bcm2835_mmc_irq > /sys/kernel/debug/tracing/set_ftrace_filter

(업데이트되는 코드)
echo bcm2835_mmc_irq > /sys/kernel/debug/tracing/set_ftrace_filter
sleep 1
echo "bcm2835_mmc_irq is enabled"

echo rpi_get_interrupt_info > /sys/kernel/debug/tracing/set_ftrace_filter
sleep 1
echo "rpi_get_interrupt_infois enabled"

Written by <디버깅을 통해 배우는 리눅스 커널의 구조와 원리> 저자



덧글

  • 조용한 에스키모 2020/10/21 14:45 # 답글

    상세한 답변 정말 감사드립니다. 확인해보니 말씀해주신대로 함수가 포함되어 있지 않았습니다.

    rpi_get_interrupt 함수를 rpi_kernel_src/linux/kernel/irq/proc.c에 포함하고 다시 커널 빌드하고 설치했습니다만... 결과는 마찬가지로 함수가 available_filter_functions에 포함되지 않네요 ㅠㅜ

    rpi_get_interrupt를 rpi_kernel_src가 아닌 본래 커널 소스 위치에서 수정해야 하는건가요?

  • AustinKim 2020/10/21 14:59 #

    책에서 설명한 내용과 같이 아래 폴더에 있는 소스를 수정해 설치하는 게 맞구요.

    root@raspberrypi:/home/pi/rpi_kernel_src/linux#

    라즈비안 커널을 빌드하고 설치하는 내용은 다음 절을 참고하시면 됩니다.

    2.3.3 라즈비안 리눅스 커널 빌드
    2.3.4 라즈비안 리눅스 커널 설치

    빌드 스크립트는 되도록 아래 링크에 있는 파일을 내려받아 그대로 사용하시길 권장드립니다.
    왜냐면 오타를 입력하면 빌드가 제대로 되지 않기 때문이죠.

    https://github.com/wikibook/linux-kernel/archive/master.zip

    rpi_get_interrupt_info() 함수가 커널 이미지에 포함됐는지 확인하는 방법은 다음과 같습니다.

    - out 폴더 이동
    root@raspberrypi:/home/pi/rpi_kernel_src# cd out

    - 아래 명령어를 입력해 'rpi_get_interrupt_info' 함수가 출력되는지 확인
    root@raspberrypi:/home/pi/rpi_kernel_src/out# objdump -d vmlinux | grep rpi_get_interrupt_info

    만약에 출력 결과에서 rpi_get_interrupt_info 함수 이름이 보이지 않으면 rpi_get_interrupt_info가 제대로 빌드되지 않은 거니,
    라즈비안 커널을 빌드하는 방법을 다시 체크하시면 되겠습니다.

    감사합니다.
  • 2020/10/21 14:59 # 답글 비공개

    비공개 덧글입니다.
  • 조용한 에스키모 2020/10/22 16:22 # 답글

    답글도 빨리 빨리 달아주시는데 자꾸 헤매서 죄송합니다만, 일단 objdump한 결과는 아래와 같이 나오는데요.
    8018a210 <rpi_get_interrupt_info>:
    8018a230:0a00000e beq8018a270 <rpi_get_interrupt_info+0x60>
    8018a268:e59f0008 ldrr0, [pc, #8]; 8018a278 <rpi_get_interrupt_info+0x68>
    8018a558:ebffff2c bl8018a210 <rpi_get_interrupt_info>

    문제는 /sys/kernel/debug/tracing/available_filter_functions에는 여전히 나오지 않습니다.

    빌드하고 설치는 다운받은 파일 그대로 했구요. 다만 실습중인 폴더가 ~/Download/rpi_kernel_src입니다. 문제가 될것 같진 않은데 이거 말고 다른건 없어서요.
    혹시 제가 파이4를 써서 그런수도 있을까요? 보니까 kernel7l, bcm2711 등으로 커널 빌드하는 것 같던데요.

    어서 책을 본격적으로 보고 싶은데 앞부분에서 계속 막혀 있네요 ㅠㅜ
  • AustinKim 2020/10/22 17:01 #

    빌드는 성공했는데, 리즈비안 커널 이미지가 제대로 설치 안된 것 같아요.
    2가지 가이드를 드리니 한번 확인 해보세요.

    1. 소스 확인
    kernel/irq/proc.c 파일을 열어 보시고,
    rpi_get_interrupt_info() 함수를 show_interrupts() 함수에서 제대로 호출됐는지 확인해주시고요.

    문제가 없다면, rpi_get_interrupt_info() 함수 왼쪽 부분에 'noinline' 키워드를 추가해보시고 빌드 및 설치를 한번 해보세요.

    (before)
    void rpi_get_interrupt_info(struct irqaction *action_p)

    (after)
    void noline rpi_get_interrupt_info(struct irqaction *action_p)

    2. 3.6절 내용 먼저 빌드

    '3.6 커널 디버깅용 Debugfs 드라이버 코드' 절에 있는 코드를 먼저 빌드하셔도 좋습니다.

    소스는 직접 입력하지 마시고, 아래 링크에 있는 코드를 다운로드해서 우선 빌드를 해보세요.
    https://github.com/wikibook/linux-kernel/archive/master.zip

    오타 때문에 제대로 동작 못할 수도 있거든요.

    3.6에 있는 코드를 빌드하면, 아래 디렉토리가 생깁니다.

    root@raspberrypi:/home/pi# ls /sys/kernel/debug/rpi_debug/
    val

    만약 위 디렉터리가 생기지 않으면, 라즈비안 커널 설치가 제대로 안 된 거라 볼 수 있어요.
  • 2020/10/22 17:01 # 답글 비공개

    비공개 덧글입니다.
  • 조용한 에스키모 2020/10/24 00:09 # 답글

    noline을 넣고 빌드하니 됩니다! 독자들 잘 챙겨주셔서 감사하구요 다시 열공하겠습니다!!
  • AustinKim 2020/10/24 07:28 #

    잘 동작하니 다행이네요.
    앞으로 실습이나 책의 내용 중에 궁금한 점이 있으면 댓글이나 이메일로 문의주세요.

    이번 문제를 한 번 정리하면...
    rpi_get_interrupt_info() 함수가 available_filter_functions 목록에 보이지 않는 이유는,
    GCC 컴파일러가 rpi_get_interrupt_info() 함수가 kernel/irq/proc.c 파일에서만 호출되니,
    "이 함수는 인라인(함수의 심벌을 없애고 함수의 코드를 함수를 호출한 부분에 복사)으로 처리"한 것으로 판단됩니다.

    참고로, rpi_get_interrupt_info() 함수의 왼쪽 부분에 noline 키워드를 추가하면,
    GCC 컴파일러에게 "지정한 함수를 인라인(line)으로 처리하지 말아라"라고 알려주는 거에요.
    그러니 rpi_get_interrupt_info() 함수의 심벌 정보가 살아 있게 되어 available_filter_functions 목록에 보이게 되는 거죠.

    그럼, 주말 잘 보내세요.
    감사합니다.
  • 2020/10/24 07:29 # 답글 비공개

    비공개 덧글입니다.
  • 사포닌 2021/03/13 12:09 # 삭제 답글

    irq_trace_ftrace.sh 실행시 "function tracer enabled" 까지만 echo되고 프리징 현상 발생...
    어찌저찌 헤메다 본 글을 읽고 noinline 추가 후 겨우 실행시켰습니다 감사합니다ㅜㅜ
    커널 설치, 셋업만 하는데도 시간을 한참 잡아먹어서 힘들지만 열심히 공부해보겠습니다.
  • AustinKim 2021/03/13 18:01 #

    그래도 이 포스트를 보시고 해결하셨다니 다행이네요.
    화이팅하세요. 감사합니다.
  • Jeon 2022/02/04 17:13 # 삭제 답글

    [리눅스커널][프로세스] 기본 유저 레벨 프로세스 실행 실습 및 ftrace 로그 분석
    해당 부분에서 ftrace 설정 및 쉘스크립트 파일 생성 시에 echo _do_fork copy_process* >> ~~에서
    마찬가지로 invalid argument error가 뜹니다. 어떤 부분이 문제일까요?

    available_filter_functions 파일에서 찾아보니 _do_fork가 없긴 합니다.
    그렇지만 _do_fork 함수 자체가 너무 중요한 시스템콜이라서 커널에 없을리도 없을테고...
    제가 직접 noline 같은 수정을 할만한 함수도 아니라서 난감합니다.


  • AustinKim 2022/02/04 21:01 #

    에러가 나는 이유는 v5.4 커널에서 _do_fork() 함수가 kernel_clone() 함수로 이름만 변경됐기 때문입니다. 아래 코드를 참고하시고요.

    https://elixir.bootlin.com/linux/v5.10.60/source/kernel/fork.c
    pid_t kernel_clone(struct kernel_clone_args *args)
    {
    u64 clone_flags = args->flags;
    struct completion vfork;

    _do_fork을 kernel_clone으로 변경하시면 되는데요.

    'echo _do_fork copy_process* >> ~' 대신에 다음과 같은 명령어를 입력하시면 됩니다.
    'echo kernel_clone copy_process* >> ~'

    리눅스 커널은 오픈 소스라 업버전이 되면서 소스가 업데이트된다는 점 이해해 주세요.

    감사합니다.
  • Jeon 2022/02/08 19:27 # 삭제 답글

    감사합니다. 잘 작동하네요. available_filter_functions에도 잘 들어 있습니다.
    감사합니다.
  • 건방진 얼음집 2022/08/24 22:16 # 답글

    윗부분 댓글 중에
    noinline(설명란) VS noline(코드부분)
    두가지로 댓글 달아주셨는데, noinline이 맞는거죠?

    라즈베리파이4 환경에
    커널은 rpi-5.15.y 입니다.

    알려주신 방법대로해도 19번 라인에 에러 메세지가 계속납니다.

    추가로 궁금한 점은 proc.c를 수정 후 rpi_kernel_src/ 폴더에 있는
    build_preprocess_rpi_kernel.sh 로 빌드 후
    install_rpi4_kernel_img.sh 로 설치하는 것인지 궁금합니다.

    kernel/irq/proc.c

    1. 소스 확인
    kernel/irq/proc.c 파일을 열어 보시고,
    rpi_get_interrupt_info() 함수를 show_interrupts() 함수에서 제대로 호출됐는지 확인해주시고요.

    문제가 없다면, rpi_get_interrupt_info() 함수 왼쪽 부분에 'noinline' 키워드를 추가해보시고 빌드 및 설치를 한번 해보세요.

    (before)
    void rpi_get_interrupt_info(struct irqaction *action_p)

    (after)
    void noline rpi_get_interrupt_info(struct irqaction *action_p)
  • AustinKim 2022/08/27 16:29 #

    방금 댓글을 확인했습니다. 확인 후 업데이트할 예정입니다.
  • 건방진 얼음집 2022/08/29 23:38 # 답글

    라즈베리파이4 8기가 메모리 스펙인데,
    커널을 설치하기 전엔 느리지 않았는데,
    일정 시간이 지나면 점점 느려집니다.

    혹시 지금 커널 버전이 rpi-5.15.y이고
    버전을 낮은걸 설치하면 속도 느려지는 현상이
    없어질까요?
    rpi-5.00.y 정도로 낮추든가
    교과서에 나와있는데로 rpi-4.19.y로 찾춰도 되는건지
    궁금합니다.
  • AustinKim 2022/09/07 00:18 #

    속도가 느려진다면 일단 최신 커널 버전 v5.15로 테스트해보시길 권장드립니다.
    조만간에 v5.15 최신 소스에서 실습하는 방법을 블로그에 업데이트할 예정입니다.

    감사합니다.
  • JohnLee 2022/09/01 15:16 # 삭제 답글

    $ cat /sys/kernel/tracing/available_filter_functions | grep <a function you care about>
    명령어를 사용하면 함수가 있는지 찾기 쉬울겁니다...만 ㅠㅠ noinline을 사용하고 커널 빌드, 설치해도 rpi_get_interrupt_info가 안 나옵니다...
    일단 위의 말씀처럼 3.6절 까지 먼저 진행하고 있겠습니다.
  • robong 2022/11/20 16:26 # 삭제 답글

    RPI4 B+ 모델 라즈비안 5.15.y 64bit 버전으로 실습 중입니다. (실습용 커널도 같은 버전입니다.)
    본문에서 설명하는 오류와 같은 에러가 11번째 줄에서 발생합니다
    11 echo secondary_start_kernel > /sys/kernel/debug/tracing/set_ftrace_filter
    line 11: echo: write error: Invalid argument

    objdump로 확인했을 때 secondary_start_kernel은 포함되어있고
    available_filter_functions에는 없었습니다.

    noinline 추가하려고 코드를 찾아보니까
    arch/arm/kernel/smp.c와 arch/arm64/kernel/smp.c 등 5개의 소스에
    secondary_start_kernel 함수가 있는데
    어떤 소스에 noinline을 써주는 게 맞을까요??
    아니면 다른 문제가 있는 걸까요??
  • AustinKim 2022/11/24 11:38 #

    'set_ftrace_filter' 파일에 함수 이름을 하나도 지정하지 않으면 available_filter_function에 있는 모든 함수를 트레이싱합니다. 그래서 자주 호출되지 않는 secondary_start_kernel 함수를 지정한 것인데요.

    send_sig_fault와 같이 거의 호출되지 않는 함수를 지정하시면 됩니다.

    echo send_sig_fault > /sys/kernel/debug/tracing/set_ftrace_filter
댓글 입력 영역