What is ‘__FILE__’ and ‘__LINE__’?

‘__FILE__ ‘, __LINE__’ 이란 무엇인가?

로그 라이브러리를 분석하던 중, __FILE__ 과 __LINE__ 이라는 구문을 발견하고 의문을 가져 내용을 찾아보았다.
아래의 주소에서 내용을 확인할 수 있었다.

http://www.codeguru.com/forum/showthread.php?t=231043

정답은 __FILE__ 과 __LINE__ 은 전처리기(Preprocessor) 에서 지정해주는 매크로라는 것.

__FILE__ 의 경우 현재 __FILE__ macro 를 사용한 파일의 이름을 나타내주고

__LINE__ 의 경우 현재 __LINE__ macro 를 사용한 파일에서 몇 번째 줄에 위치했는지를 나타내준다.

이와 비슷한 전처리기 매크로는

  • ‘__DATE__’ -> a string literal of the form “Mmm dd yyyy”
  • ‘__TIME__’ -> a string literal of the form “hh:mm:ss”
  • ‘__TIMESTAMP__’ -> a string literal of the form “Mmm dd yyyy hh:mm:ss”
  • ‘__FUNCTION__’ -> a string literal which contains the function name (this is part of C99, the new C standard and not all C++ compilers support it)

가 있다.

아래는 __FILE__ 과 __LINE__ 을 이용한 예제와 결과이다.

#include 

int main(int argc, char** argv)
{
        printf("%s:%dn", __FILE__, __LINE__);
        return 0;
}

결과

jonathan@jonathan-laptop:~/Desktop/temp/test$ ./test
test.c:6

undefined reference to `SSL_CTX_free’

 

사내에서 개발중인 제품을 테스트하기 위해 컴파일을 하던 도중, 아래의 오류를 발견했다. mysqlclient 라이브러리를 함께 사용하는 부분이 있었는데, Linking 을 하던 도중 에러가 발생한 것이다.

/usr/lib/mysql/libmysqlclient.a(client.o): In function `mysql_close_free_options’:
(.text+0xd7d): undefined reference to `SSL_CTX_free’
/usr/lib/mysql/libmysqlclient.a(client.o): In function `mysql_get_ssl_cipher’:
(.text+0x1081): undefined reference to `SSL_get_current_cipher’
/usr/lib/mysql/libmysqlclient.a(client.o): In function `mysql_real_connect’:
(.text+0x3a4c): undefined reference to `SSL_get_peer_certificate’
/usr/lib/mysql/libmysqlclient.a(client.o): In function `mysql_real_connect’:
(.text+0x3a60): undefined reference to `X509_get_subject_name’
/usr/lib/mysql/libmysqlclient.a(client.o): In function `mysql_real_connect’:
(.text+0x3a74): undefined reference to `X509_NAME_oneline’
/usr/lib/mysql/libmysqlclient.a(client.o): In function `mysql_real_connect’:
(.text+0x3a7c): undefined reference to `X509_free’
/usr/lib/mysql/libmysqlclient.a(client.o): In function `mysql_get_ssl_cipher’:
(.text+0x108a): undefined reference to `SSL_CIPHER_get_name’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `report_errors’:
(.text+0x45): undefined reference to `ERR_get_error_line_data’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `ssl_do’:
(.text+0x8c): undefined reference to `SSL_new’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `ssl_do’:
(.text+0x9a): undefined reference to `SSL_clear’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `ssl_do’:
(.text+0xa2): undefined reference to `SSL_get_session’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `ssl_do’:
(.text+0xae): undefined reference to `SSL_SESSION_set_timeout’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `ssl_do’:
(.text+0xbc): undefined reference to `SSL_set_fd’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `ssl_do’:
(.text+0xd1): undefined reference to `SSL_get_fd’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `ssl_do’:
(.text+0x14b): undefined reference to `SSL_free’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `sslconnect’:
(.text+0x16f): undefined reference to `SSL_connect’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `sslaccept’:
(.text+0x18f): undefined reference to `SSL_accept’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `vio_ssl_close’:
(.text+0x1c5): undefined reference to `SSL_set_quiet_shutdown’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `vio_ssl_close’:
(.text+0x1cd): undefined reference to `SSL_shutdown’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `vio_ssl_delete’:
(.text+0x212): undefined reference to `SSL_free’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `vio_ssl_write’:
(.text+0x261): undefined reference to `SSL_write’
/usr/lib/mysql/libmysqlclient.a(viossl.o): In function `vio_ssl_read’:
(.text+0x281): undefined reference to `SSL_read’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `report_errors’:
(.text+0x25): undefined reference to `ERR_get_error_line_data’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x99): undefined reference to `SSL_CTX_new’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0xbc): undefined reference to `SSL_CTX_set_cipher_list’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0xd9): undefined reference to `SSL_CTX_load_verify_locations’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0xfb): undefined reference to `SSL_CTX_use_certificate_file’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x125): undefined reference to `SSL_CTX_use_PrivateKey_file’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x135): undefined reference to `SSL_CTX_check_private_key’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x142): undefined reference to `DH_new’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x166): undefined reference to `BN_bin2bn’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x185): undefined reference to `BN_bin2bn’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x1bb): undefined reference to `SSL_CTX_ctrl’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x1c3): undefined reference to `DH_free’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x1da): undefined reference to `SSL_load_error_strings’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x1eb): undefined reference to `SSL_library_init’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x1f0): undefined reference to `OPENSSL_add_all_algorithms_noconf’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x206): undefined reference to `SSL_CTX_set_default_verify_paths’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x21d): undefined reference to `SSL_CTX_free’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x2bd): undefined reference to `DH_free’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLFd’:
(.text+0x2d6): undefined reference to `SSL_CTX_free’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLAcceptorFd’:
(.text+0x328): undefined reference to `TLSv1_server_method’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLAcceptorFd’:
(.text+0x36f): undefined reference to `SSL_CTX_ctrl’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLAcceptorFd’:
(.text+0x389): undefined reference to `SSL_CTX_set_verify’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLAcceptorFd’:
(.text+0x39f): undefined reference to `SSL_CTX_set_session_id_context’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLConnectorFd’:
(.text+0x3c6): undefined reference to `TLSv1_client_method’
/usr/lib/mysql/libmysqlclient.a(viosslfactories.o): In function `new_VioSSLConnectorFd’:
(.text+0x405): undefined reference to `SSL_CTX_set_verify’
/usr/lib/mysql/libmysqlclient.a(my_compress.o): In function `my_uncompress’:
(.text+0x60): undefined reference to `uncompress’
/usr/lib/mysql/libmysqlclient.a(my_compress.o): In function `my_compress_alloc’:
(.text+0x102): undefined reference to `compress’
collect2: ld returned 1 exit status
make: *** [nxstart] 오류 1

위의 오류는 ssl 관련 라이브러리를 찾지 못해서 발생되는 오류였다. 보통 SSL 라이브러리의 경우 MySQL 이 설치될때 같이 설치가 되는 것 같았는데 이번엔 조금 경우가 특이했다.

OS는 64비트 였지만 제품은 32 비트로 컴파일 해야 했던 것. 처음에는 약간 헤매었지만 결국 해결할 수 있었다.

OS:

Linux localhost.localdomain 2.6.18-238.el5 #1 SMP Thu Jan 13 15:51:15 EST 2011 x86_64 x86_64 x86_64 GNU/Linux

SSL 라이브러리 설치:

# yum install openssl-devel.i386

SSL 라이브러리 추가:

-lssl

 

How to use gdb in Multi Threaded Network Program

 

Stack Overflow 에서 상당히 유용한 스레드를 발견하여 이곳에 싣는다.

내용은 멀티 스레드 환경에서 네트워크 프로그램을 디버그 할 때 어떻게 gdb를 사용하는가? 이다.

 

Enable core dump saving in your environment. Run command ulimit -c unlimited and rerun your program. When it crashes, load generated core dump in gdb and look backtraces of crash. In case of multi threaded program it is convenient to obtain backtraces from all threads by one command at once: (gdb) thread apply all bt.

 

결론적으로 다음의 한 줄로 요약될 수 있다.

(gdb) thread apply all bt

원글의 주소는 아래와 같다.

http://stackoverflow.com/questions/6813629/how-do-i-use-gdb-for-multi-threaded-networking-program

 

 

 

stack smashing detected

프로그램 TEST 중 아래와 같은 오류가 발생했다.

결과는 Core dump.

jonathan@jonathan-laptop:~/workspace/TEST$ ./TEST
*** stack smashing detected ***: ./TEST terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x50)[0xb775c390]
/lib/tls/i686/cmov/libc.so.6(+0xe233a)[0xb775c33a]
./TEST[0x804a2f4]
./TEST[0x8049189]
./TEST[0x8049258]
./TEST[0x8049205]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb7690bd6]
./TEST[0x8049081]
======= Memory map: ========
08048000-0804f000 r-xp 00000000 08:05 7344439    /home/jonathan/workspace/TEST/TEST
0804f000-08050000 r–p 00007000 08:05 7344439    /home/jonathan/workspace/TEST/TEST
08050000-08051000 rw-p 00008000 08:05 7344439    /home/jonathan/workspace/TEST/TEST
08051000-080fd000 rw-p 00000000 00:00 0
09a2c000-09a4d000 rw-p 00000000 00:00 0          [heap]
b763d000-b765a000 r-xp 00000000 08:05 4849747    /lib/libgcc_s.so.1
b765a000-b765b000 r–p 0001c000 08:05 4849747    /lib/libgcc_s.so.1
b765b000-b765c000 rw-p 0001d000 08:05 4849747    /lib/libgcc_s.so.1
b7678000-b767a000 rw-p 00000000 00:00 0
b767a000-b77cd000 r-xp 00000000 08:05 4984558    /lib/tls/i686/cmov/libc-2.11.1.so
b77cd000-b77ce000 —p 00153000 08:05 4984558    /lib/tls/i686/cmov/libc-2.11.1.so
b77ce000-b77d0000 r–p 00153000 08:05 4984558    /lib/tls/i686/cmov/libc-2.11.1.so
b77d0000-b77d1000 rw-p 00155000 08:05 4984558    /lib/tls/i686/cmov/libc-2.11.1.so
b77d1000-b77d4000 rw-p 00000000 00:00 0
b77ef000-b77f2000 rw-p 00000000 00:00 0
b77f2000-b77f3000 r-xp 00000000 00:00 0          [vdso]
b77f3000-b780e000 r-xp 00000000 08:05 4855235    /lib/ld-2.11.1.so
b780e000-b780f000 r–p 0001a000 08:05 4855235    /lib/ld-2.11.1.so
b780f000-b7810000 rw-p 0001b000 08:05 4855235    /lib/ld-2.11.1.so
bff3e000-bff53000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)

원인 분석을 위해 코어 파일과 함께 gdb를 실행 시켜 보았다.

jonathan@jonathan-laptop:~/workspace/TEST$ gdb -c core TEST
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type “show copying”
and “show warranty” for details.
This GDB was configured as “i486-linux-gnu”.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>…
Reading symbols from /home/jonathan/workspace/TEST/TEST…done.
[New Thread 5966]

warning: Can’t read pathname for load map: Input/output error.
Reading symbols from /lib/tls/i686/cmov/libc.so.6…(no debugging symbols found)…done.
Loaded symbols for /lib/tls/i686/cmov/libc.so.6
Reading symbols from /lib/ld-linux.so.2…(no debugging symbols found)…done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /lib/libgcc_s.so.1…Reading symbols from /usr/lib/debug/lib/libgcc_s.so.1…done.
done.
Loaded symbols for /lib/libgcc_s.so.1
Core was generated by `./TEST’.
Program terminated with signal 6, Aborted.
#0  0xb77f2430 in __kernel_vsyscall ()
(gdb) where
#0  0xb77f2430 in __kernel_vsyscall ()
#1  0xb76a4651 in raise () from /lib/tls/i686/cmov/libc.so.6
#2  0xb76a7a82 in abort () from /lib/tls/i686/cmov/libc.so.6
#3  0xb76db49d in ?? () from /lib/tls/i686/cmov/libc.so.6
#4  0xb775c390 in __fortify_fail () from /lib/tls/i686/cmov/libc.so.6
#5  0xb775c33a in __stack_chk_fail () from /lib/tls/i686/cmov/libc.so.6
#6  0x0804a2f4 in TestHeadMake () at test.c:515
#7  0x08049189 in TestLog (loglvl=1, title=0x804df59 “TEST”, fmt=0x804df57 “n”) at test.c:196
#8  0x08049258 in StartMessage () at test.c:237
#9  0x08049205 in main (argc=1, argv=0xbff509a4) at test.c:218

문제는 간단했다.

함수 TestHeadMake() 내에서 사용하는 문자열 버퍼 timeStr 의 사이즈가 데이터를 담기에 작았던 것.

바로 찾아서 해결을… 했으면 좋았겠지만 한참을 찾았다…;;

“/opt/aCC/include_std/utility”, line 99: error #2070: incomplete type is not allowed

HP 장비에서 aCC 로 컴파일을 하던도중 아래의 에러가 발생했다.

“/opt/aCC/include_std/utility”, line 99: error #2070: incomplete type is not
allowed
first_type  first;
^
detected during:
instantiation of class “std::pair<_TypeT, _TypeU> [with
_TypeT=const std::string, _TypeU=char *]” at line 97 of
“/opt/aCC/include_std/rw/tree”
instantiation of class “__rw::__rw_rb_tree_node<_Alloc, _Val,
_Key, _KeyOf> [with
_Alloc=std::allocator<std::pair<const std::string, char
*>>, _Val=std::pair<const std::string, char *>,
_Key=std::string,
_KeyOf=__rw::__select1st<std::pair<const std::string,
char *>, std::string>]” at line 282 of
“/opt/aCC/include_std/rw/tree”
instantiation of class “__rw::__rb_tree<_Key, _Val, _KeyOf, _Comp,
_Alloc> [with _Key=std::string, _Val=std::pair<const
std::string, char *>,
_KeyOf=__rw::__select1st<std::pair<const std::string,
char *>, std::string>, _Comp=std::less<std::string>,
_Alloc=std::allocator<std::pair<const std::string, char
*>>]” at line 102 of “/opt/aCC/include_std/map”
instantiation of class “std::map<_Key, _TypeT, _Compare,
_Allocator> [with _Key=std::string, _TypeT=char *,
_Compare=std::less<std::string>,
_Allocator=std::allocator<std::pair<const std::string,
char *>>]” at line 54 of “LocalRepository.h”

이유인즉, HP 컴파일러 aCC 가 버전 6로 넘어오면서 기존(aCC version 5)에서 허용했던 C++ 타입에 대한 처리를 더이상 허용하지 않으면서 발생한 문제였다.

관련링크 : http://h21007.www2.hp.com/portal/site/dspp/menuitem.863c3e4cbcdc3f3515b49c108973a801/?ciid=2708d7c682f02110d7c682f02110275d6e10RCRD#_iso-39._acc6_detects_instantiation_

공식 문서내용은 다음과 같다.

ISO-39. aCC6 detects instantiation conflicts earlier (2403)

Points of instantiation differ for member functions, so reporting of instantiation conflicts can differ. This is simply a behavior difference, and not a compatibility issue. However, the following code snippet illustrates an incompatibility in the use of repeated const keywords, which aCC5 allows and aCC6 does not. To fix this code, don’t instantiate the template with a const int; simply use int:

template <class T>
struct S {
void foo(T *i) {}
void foo(const T *i) {}
};
int main() {
int i = 5;
#ifdef WORKS_IN_BOTH
S<int> s;
#else
S<const int> s;
#endif
return 0;
}

내용인즉, C++ 에서 template 사용시 const 를 사용하지 말라는 뜻이다.

위의 에러에서 문제가 해당 라인(line 54 of “LocalRepository.h”)을 찾아가보니 아래와 같이 선언되있었다.

map<string, char*> m_mapStringMainData;

뭔가 이상했다. map 선언 중, 어디에도 const 는 있지 않았다. 어찌된 일일까.

한참을 헤매고 주위에 도움을 구해서 찾아낸 정답은 정말 엉뚱한 곳에 있었다.
바로 iostream 였다.

다음의 라인을 추가하여 깔끔히 문제를 해결할 수 있었다.

#include <iostream>

왜 이런 문제가 생긴 것일까? 조금 더 질문을 해본 결과 한가지 재미있는 사실을 알 수 있었다.
이전 버전의 aCC 에서는 iostream 을 include 하면 또 안된다는 것..

아직 배워야할 것이 많다..