[질문] Segmentation fault

seemajor의 이미지

현재 gdb에서 디버깅을 하다가 문제가 되는 부분의 코드를 유심히 보았지만 왜 자꾸 segmentation fault가 나는지를 모르겠습니다.
한 수 가르침을 부탁드립니다.

참고로 제가 직접 짠 코드는 아닙니다.

공부하려고 받은 코드인데 수정작업중입니다.

하다가 결국 이 부분에서 막혀서 질문란에 올린 것이니 왜 어렵게 코드를 작성했느니 인자값을 왜 그렇게 넣었냐느니 물으시면 저로서도 할말이 없습니다.
아래부터 코드입니다.

/*
* 저장된 채널의 주파수값을 읽어오는 함수
*/

unsigned long int channel_to_freq(int get_channel, int freq_type)
{
	struct channel *tmp_channel;
	long ret_freq;
	int channel_tmp, cnt;

	tmp_channel = get_channel_list(freq_type);

	cnt=0;
	while(1) {

		channel_tmp = atoi((tmp_channel+cnt)->ch_num);
		if( channel_tmp == get_channel ) 	break;

		cnt++;
	}

	ret_freq = atol((tmp_channel+cnt)->ch_freq);

	return ret_freq;

}

이 함수는 메인 함수에서

current_freq = channel_to_freq( 1, FQBCAST); 로 콜됩니다.

자료형은 unsigned long current_freq; 입니다.

channel_to_freq 함수의 프로토 타입은 아래와 같습니다.

_____________________________________________
/*주파수 타입을 입력 받아 채널정보가 기록된 버퍼의 주소값 리턴*/

unsigned long int channel_to_freq(int get_channel, int freq_type); ------------------------------------------------------------------------

구조체 channel은 다음과 같습니다.

struct channel {
	char ch_name[5]; //채널 이름
	char ch_num[3];  //채널 넘버
	char ch_freq[7]; //주파수
//	long ch_freq_int; //주파수
};

gdb툴로 메인 함수의 current_freq = channel_to_freq( 1, FQBCAST); 부분을 breakpoint로 잡고 running을 해봤습니다.

실행되다가 signal SIGSEGV를 나타내었고, backtrace를 해봤더니 아래와 같은 메시지가 나왔습니다.

_____________________________________________

(gdb) bt
#0 0x4202b0fa in __strtol_internal() from /lib/tls/libc.so.6
#1 0x42028839 in atoi() from /lib/tls/libc.so.6
#2 0x0804b8b6 in channel_to_freq()
#3 0x0804e1aa in main(argc=1, argv=0xbffff6b4) at xxxxx-1.0.c:628
#4 0x42015574 in __libc_start_main() from /lib/tls/libc.so.6
(gdb)

여기에서 보니 atoi() 함수가 문제가 되는거 같거든요.

뭐가 문제인지 부탁 좀 드립니다. 여러분

kslee80의 이미지

(tmp_channel+cnt)->ch_freq atoi() 의 인자로 넘어간 이 코드의 의도가 무엇이신지요? 제가 보기에는 get_channel_list() 가 struct channel 의 array 를 리턴하기 때문에 그 array 를 이용하기 위해서 저런 코드를 작성하신거 같네요..

만약에 그래서 저렇게 했다면,
저 부분에서 Segmentation fault 가 되겠네요.
어째서인지는 조금만 생각해 보시면 아실듯 싶네요.

익명 사용자의 이미지

kslee80님,

atoi 함수의 인자값이 (tmp_channel+cnt)->ch_freq가 아니라(tmp_channel+cnt)->ch_num을 말씀하시는거죠?

익명 사용자의 이미지

포인터를 리턴하게 한다면 항상 포인터의 유효성(valid?)을 검사하세요.

	tmp_channel = get_channel_list(freq_type);
	if ( tmp_channel == ( struct channel *)0 ) {
                      ....
                }

루프에서 (tmp_channel+cnt)가 valid한가?검사후 처리
대략 아래를,
channel_tmp = atoi((tmp_channel+cnt)->ch_num);
다음과 같이....
if ( tmp_channel+cnt == valid pointer? 포인터검사) // 이경우에는 cnt값의 유효성검사가 필요해 보입니다. if( cnt < MAX_CNT)와 같은....
{
   channel_tmp = atoi((tmp_channel+cnt)->ch_num);
   ...
}
else {
  에러처리;
}

대략 위와 같은 유형이겠습니다.

* 총체적으로, cnt값이 유효한가?검사하는게 옳겠습니다.
* cnt가 가질수 있는 최대치, 또는 그 배열의 마지막에 0(NULL)이 들어 있는지를 검토하세요.

cdpark의 이미지

kslee80 wrote:
(tmp_channel+cnt)->ch_freq
atoi() 의 인자로 넘어간 이 코드의 의도가 무엇이신지요?

의도적으로 어렵게 쓴 코드죠. :)

tmp_channel[cnt].ch_freq 라고 썼으면 읽기 쉬웠겠죠?

그리고 ch_num이나 ch_freq가 숫자라면 배열을 쓰지 말고 바로 int형을 쓰는게 어떨까요?

ch_num 등은 '\0'으로 끝나겠죠?

그리고 5/3/7바이트처럼 정렬하기 힘든 크기를 준 이유라도?

seemajor의 이미지

참고로 제가 직접 짠 코드는 아닙니다.

공부하려고 받은 코드인데 수정작업중입니다.

하다가 결국 이 부분에서 막혀서 질문란에 올린 것이니 왜 어렵게 코드를 작성했느니 인자값을 왜 그렇게 넣었냐느니 물으시면 저로서도 할말이 없습니다.

가급적 많은 답변을 보고 싶습니다.

익명 사용자의 이미지

Svn 에서 특정버전의 특정파일이 업데이트가 되지 않습니다.
현재는 200 버전을 넘어 있는데
188 에서 191 까지 특정 파일을 업데이트할때 문제가
read strings fail 이라는 비슷한 멘트가 발생됩니다

이문제를 해결하기 위해 뭐를 하면 될까요..??

익명 사용자의 이미지

ch_num[] 혹은 ch_freq[] 가 null-terminated string 이 아닌가 보내요.

익명 사용자의 이미지

그런데 재수가 없어서 ... break; 에 안걸리면..

저 While loop 는 언제 끝나나요?

댓글 달기

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