시스템 콜에 call-by-value를 통한 구조체 매개변수 전달에 관해 궁금합니다.

rainbowline의 이미지

시스템 콜 함수를 구현하고 있는데 해당 시스템 콜 매개변수로 구조체를 넘겨주고 싶습니다.
예를 들면 다음과 같습니다.

typedef struct _a {
int i;
char c[4];
int j;
int k;
int l;
} a;

asmlinkage int sys_mysyscall(int index, a mypara) { ... }

현재 이렇게 구현해 놓고 있으며
(kernel)/include/linux/syscalls.h 의 가장 하단에 위의 { } 을 ; 로 바꿔 넣어놓았습니다.

발생하는 문제는 해당 시스템 콜 호출 시 구조체의 마지막 부분이 예측되지 못하는 값으로 할당됩니다.
예를 들어 mypara.l 에 0 을 할당해서 넘겨주었는데 시스템 콜 내부에서 확인한 결과 -38이 저장되있는 식입니다.
해당 문제에 관하여 찾아보니 구조체를 넘길 땐 대부분 포인터를 통해 넘기는데 이런 식으로 call-by-value 형태로 넘길 수는 없는건지
궁금합니다.

※위 구현 내용은 이름을 제외하면 구조체 내부 변수의 개수 및 타입이라던지 매개변수의 개수 및 타입은 완전하게 동일합니다.

dltkddyd의 이미지

이런 생성자를 구조체 안에 만드셔야 합니다.

struct_a(const struct_a& src) {
  i=src.i;
  j=src.j;
  k=src.k;
  l=src.l;
  for(unsigned long int i=0;i<4;i++) {
    c[i]=src.c[i];
  }
}

구조체로 선언된 변수도 하나의 객체로 보십시오. 다만 구조체는 기본적으로 public 멤버라는 사실만 다릅니다. 만약 이 부분이 이해가 잘 안되신다면 C++ 클래스와 구조체를 비교하면서 자료를 찾아보세요.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

rainbowline의 이미지

다시 질문드려서 죄송합니다만 궁금한 점이 있어서 답글 남겨요.

1. 형식이 함수에 가까운데 저 ( ) 내부가 어떻게 들어가는지 궁금하네요.
struct _a(const struct _a &src) { } <- 이런 형식의 함수인건가요?

2. 저걸 구조체 않에 넣어야 된다고 하셨는데 그럼 결론적으로
typedef struct _a {
int i;
...

struct _a(const struct _a &src) { ... }
} a;

이런식으로 되어야 한다는 말씀이신가요?
이런 형식이 가능한지 궁금하네요.

※ 사실 Kernel 내부에 C++의 내용을 넣을 수 있는지 궁금하네요.
자세히 찾아보진 않았지만 구조체에 생성자를 넣는건 C++에서 사용하더라구요.

익명 사용자의 이미지

1. 형식이 함수에 가까운데 저 ( ) 내부가 어떻게 들어가는지 궁금하네요.
struct _a(const struct _a &src) { } <- 이런 형식의 함수인건가요?

답변) 흔히 생성자라고 합니다. 선언자와 동일한 이름으로 만들어진 생성자이며, 일반적인 멤버함수와는 달리 반환값이 없다는 것이 특징입니다. 일반함수는 선언과 정의시 반환값을 언급하도록 돼있지만 생성자는 그렇지 않습니다. 그리고 저런 생성자를 정의해놓으면, 질문하신 내용처럼 함수로 값을 전달할 때 저 생성자가 호출되도록 돼있습니다.

2. 저걸 구조체 않에 넣어야 된다고 하셨는데 그럼 결론적으로
typedef struct _a {
int i;
...

struct _a(const struct _a &src) { ... }
} a;

이런식으로 되어야 한다는 말씀이신가요?

답변) 네, 그렇습니다. 그리고 답변은 C++을 기준으로 말씀드린 겁니다.

정 안된다면 레퍼런스를 사용하는 것도 좋은 방법일 수 있습니다. C++이 강력한 것은 바로 이 타입을 프로그래머가 자유자재로 만들 수 있다는 데 있는 것이죠.

dltkddyd의 이미지

struct _a가 아니라 그냥 _a이군요. 답글 수정합니다.

본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.

klara의 이미지

C의 구조체는 생성자라는 개념자체가 없습니다.

mirheekl의 이미지

내부에서 포인터를 사용해서 다른 객체를 가리키거나 동적 메모리를 사용하거나 하지 않는 한에는 그냥 돼야 정상입니다. 본문의 코드도 문제를 찾을 수 없네요. 일반적으로 포인터로 넘기는 이유는 첫째 구조체가 커질 경우 복사 자체가 비효율적이고 둘째 값을 복사해서 전달받으므로 변경된 내용을 caller에게 전달할 수 없기 때문입니다. 시스템 콜 말고 일반 프로그램에서 테스트해 보세요. 아무 문제없이 잘 될것입니다.

현재 사용하신 인자 전달 규약으로 스택을 통해 커널에 전달할 수 있는 데이터량에 타이트한 제한이 있는 걸로 생각이 됩니다. 마침 딱 4개의 32비트 값까지만 전달되고 잘린걸로 봐서 강력히 의심이 됩니다. asmlinkage의 설명에도 그런 내용이 있고요. 구조체 사이즈를 조금 줄인 뒤 다시 테스트해보시면 알 수 있겠죠. 그러고 보니 이것도 call by value가 덜 쓰이는 이유가 될 수 있겠네요.

--

댓글 달기

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