CS50 Appliance에서 문제를 풀다가 에러가 발생해서 디버깅을 하는데 아무리 print 'variable'을 해도 값이 출력되지 않고 No Symbol 'variable' in current context
에러만 발생하길래 소스를 잘못 작성했나 싶어 좀 살펴보았다. 검색을 해보니 다행히 소스코드의 문제는 아닌 것 같고 GDB 자체의 문제인듯 하다.
보통의 경우에 이런 에러메시지가 출력된다면 다음과 같이 해본다.
- 컴파일 옵션에서 optimize 레벨을 0으로 지정한다. 컴파일시 optimizing을 할경우 실제로 변수가 저장되는 위치나 순서가 변경될 수 있다고 한다.
예) clang -O0
- GDB에서
info frame
이나info locals
등의 명령어를 통해 스택 번호가 실제로 일치하는지 확인한다.
그런데 이 문제의 경우에는 위의 두 가지로도 해결이 되지 않았다. 좀더 검색을 해보니 GDB 자체에서 배열의 크기를 변수로 지정했을 경우 배열의 값을 제대로 출력하지 못하는 문제가 있는 것 같았다. VLA(Vaiable Length Array) 문제라고 하던데 GDB 7.8에서는 아래 인용문처럼 문제가 해결되었다고 한다. 하지만 CS50 Appliance는 7.7을 사용하고 있어서 결국 제대로 된 결과는 볼 수 없었다.
Tue, 29 Jul 2014
GDB 7.8 brings new targets, features and improvements, including:
...
ISO C99 variable length automatic arrays support.
Update
보다 근본적으로는 배열의 크기에 변수를 넣은 것이 문제인 것 같다. 물론 C99에서 부터는 배열의 크기에 변수를 넣는 것도 일부 허용된다고는 한다.
Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++. These arrays are declared like any other automatic arrays, but with a length that is not a constant expression. The storage is allocated at the point of declaration and deallocated when the block scope containing the declaration exits. For example:
FILE *
concat_fopen (char *s1, char *s2, char *mode)
{
char str[strlen (s1) + strlen (s2) + 1];
strcpy (str, s1);
strcat (str, s2);
return fopen (str, mode);
}
참고
- http://stackoverflow.com/questions/25161133/gcc-does-not-produce-debugging-symbols-for-local-variable-length-arrays-or-gdb
- http://stackoverflow.com/questions/25161133/gcc-does-not-produce-debugging-symbols-for-local-variable-length-arrays-or-gdb
- https://sourceware.org/gdb/wiki/VariableLengthArray
- https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html