시스템 콜에 call-by-value를 통한 구조체 매개변수 전달에 관해 궁금합니다.
글쓴이: rainbowline / 작성시간: 화, 2014/05/06 - 1:27오후
시스템 콜 함수를 구현하고 있는데 해당 시스템 콜 매개변수로 구조체를 넘겨주고 싶습니다.
예를 들면 다음과 같습니다.
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 형태로 넘길 수는 없는건지
궁금합니다.
※위 구현 내용은 이름을 제외하면 구조체 내부 변수의 개수 및 타입이라던지 매개변수의 개수 및 타입은 완전하게 동일합니다.
Forums:
구조체도 클래스로 인식하시면 이해가 쉽습니다.
이런 생성자를 구조체 안에 만드셔야 합니다.
구조체로 선언된 변수도 하나의 객체로 보십시오. 다만 구조체는 기본적으로 public 멤버라는 사실만 다릅니다. 만약 이 부분이 이해가 잘 안되신다면 C++ 클래스와 구조체를 비교하면서 자료를 찾아보세요.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
저건 함수 형식인건가요?
다시 질문드려서 죄송합니다만 궁금한 점이 있어서 답글 남겨요.
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++이 강력한 것은 바로 이 타입을 프로그래머가 자유자재로 만들 수 있다는 데 있는 것이죠.
윗글에서
struct _a가 아니라 그냥 _a이군요. 답글 수정합니다.
본인 맞습니다.
인증샷
우헤헤헤... 로 대신합니다.
C의 구조체는 생성자라는 개념자체가 없습니다.
C의 구조체는 생성자라는 개념자체가 없습니다.
구조체도 call by value로 그냥 전달 가능합니다.
내부에서 포인터를 사용해서 다른 객체를 가리키거나 동적 메모리를 사용하거나 하지 않는 한에는 그냥 돼야 정상입니다. 본문의 코드도 문제를 찾을 수 없네요. 일반적으로 포인터로 넘기는 이유는 첫째 구조체가 커질 경우 복사 자체가 비효율적이고 둘째 값을 복사해서 전달받으므로 변경된 내용을 caller에게 전달할 수 없기 때문입니다. 시스템 콜 말고 일반 프로그램에서 테스트해 보세요. 아무 문제없이 잘 될것입니다.
현재 사용하신 인자 전달 규약으로 스택을 통해 커널에 전달할 수 있는 데이터량에 타이트한 제한이 있는 걸로 생각이 됩니다. 마침 딱 4개의 32비트 값까지만 전달되고 잘린걸로 봐서 강력히 의심이 됩니다. asmlinkage의 설명에도 그런 내용이 있고요. 구조체 사이즈를 조금 줄인 뒤 다시 테스트해보시면 알 수 있겠죠. 그러고 보니 이것도 call by value가 덜 쓰이는 이유가 될 수 있겠네요.
--
댓글 달기