리눅스 커널 최신 버전에서는 memcpy 함수를 사용할 수 없나요?

익명 사용자의 이미지

커널 5.8 버전에서 간단한 디바이스 드라이버를 작성중인데, memcpy나 memset 함수를 사용하고 커널에 적재하니 아예 함수가 사라져 버립니다. 어셈으로 디버깅해봐도 아예 사라져 있구요.

4버전대에선 memcpy를 쓸 수 있었던거 같은데, 최신 커널에서는 사용할 수 없는건가요? 아니면 그냥 휴먼 에러인가요?

bushi의 이미지

함수가 사라진다는 말이 무슨 뜻인가요 ?
https://elixir.bootlin.com/linux/latest/A/ident/memcpy

답을 골라야한다면, 휴먼 에러라는 쪽에 50원 걸겠습니다.

익명 사용자의 이미지

static ssize_t test_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) {
    char arr[8] = { [0 ... 7] = 0 };
    char *ptr;
 
    ptr = (char *)kmalloc(count, GFP_KERNEL);
 
    copy_from_user(ptr, buf, count);
 
    memcpy(arr, ptr, 8);  // wtf
 
    return 0;
}

file_operations에 write로 등록된 함수입니다.
위 코드에서 memcpy 부분이 작동을 안해서 어셈으로 확인해 봤더니

   0xffffffffc0000000:	push   r12
   0xffffffffc0000002:	mov    rdi,rdx
   0xffffffffc0000005:	mov    r12,rdx
   0xffffffffc0000008:	push   rbp
   0xffffffffc0000009:	mov    rbp,rsi
   0xffffffffc000000c:	mov    esi,0xcc0
   0xffffffffc0000011:	call   0xffffffff811d5930 <__kmalloc>
   0xffffffffc0000016:	cmp    r12,0x7fffffff
   0xffffffffc000001d:	ja     0xffffffffc0000033
   0xffffffffc000001f:	mov    rdi,rax
   0xffffffffc0000022:	mov    rdx,r12
   0xffffffffc0000025:	mov    rsi,rbp
   0xffffffffc0000028:	call   0xffffffff813dcc20 <_copy_from_user>
   0xffffffffc000002d:	xor    eax,eax
   0xffffffffc000002f:	pop    rbp
   0xffffffffc0000030:	pop    r12
   0xffffffffc0000032:	ret
   0xffffffffc0000033:	ud2

이와 같이 memset이 아예 사라져 버렸습니다. 이거 설마 undefined behavior 일까요? undefined behavior가 아예 함수 호출을 스킾하는 경우도 있나요..?

jick의 이미지

arr는 로컬 변수인데 함수가 끝나면 아무 역할도 못하고 사라지겠죠. 따라서 컴파일러가 보기에 memcpy가 있으나 마나 프로그램의 진행에 아무런 영향이 없습니다. 그러므로 최적화 과정에서 날려 버릴 수 있습니다.

익명 사용자의 이미지

테스트 해보니 gcc의 최적화 때문이 맞았네요. gcc 10으로 업데이트 한 뒤에 뭔가 최적화가 더 빡세진? 느낌입니다.. 답변 감사합니다.

bushi의 이미지

"커널에 적재" 하니 "함수가 사라졌다"고 쓰는대신,

"컴파일 된 바이너리" 에서 "함수 호출 부분이 사라졌다" 고 썼다면 아마도 질문글을 쓰는 도중에 본인이 스스로 답을 찾았을 것 같습니다.
그 정도 최적화는 gcc 2.x 에도 있었습니다.
점점 더 빡세 진 것은 함수를 inline 시켜버리는 쪽이고... 언뜻 보면 디버깅 정보에 심볼들이 보여서 inline 안되고 남아있는 것 처럼 보여도, call 대신 jump 를 쓰면서 스택 프레임을 바꾸지 않는 코드를 만들어내는 바람에 나중에 back trace 때 함수 호출 경로에 듬성등성 이빨이 빠져서 상당한 혼란을 겪죠.

익명 사용자의 이미지

memset -> memcpy

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.