怎么知道gcc搜索头文件的路径

每个C/C++程序员都知道,对于#include directive,一般,以双引号引用的头文件是程序号自定义的头文件。而用尖括号引用的头文件是系统的头文件或其它库文件。

更详细的,编译器先在当前目录找用双引号""引用的头文件,如果找不到再到系统目录找这个头文件。而对于尖括号引用的头文件,编译器就只在系统文件中搜索了。

那么,到底是在哪些目录中搜索头文件呢?

可以用cpp查看,如下:

root@vicarious:/home/kamus/projs/horoscope/boost# cpp -v
Using built-in specs.
COLLECT_GCC=cpp
Target: x86_64-linux-gnu
Thread model: posix
gcc version 4.7.2 (Debian 4.7.2-5) 
COLLECT_GCC_OPTIONS='-E' '-v' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.7/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu - -mtune=generic -march=x86-64
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.7/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

 

一般编写makefile时给gcc指定 -I选项,-I的参数代表的目录是搜索系统头文件时使用的目录。可以试试# cpp -I/tmp -v 

/tmp目录会被添加为搜索系统头文件时的第一个目录。

如果想要添加搜索双引号""引用的头文件使用的目录呢,用 -iquote 选项指定更多的目录。

copyright blog.ykyi.net

Linux的环境变量LD_DEBUG调试so的加载

一个稍微有经验的Linux程序员都知道使用LD_LIBRARY_PATH 来临时设置加载器搜索动态链接库so的路径顺序。但另一个不为人知的环境变量是LD_DEBUG。这个变量可以提供非常详细的加载动态链接库的信息。

 

可以把LD_DEBUG设成以下值:

export LD_DEBUG=files     # 显示库的依赖性和加载的顺序

export LD_DEBUG=bindings  # 符号绑定

export LD_DEBUG=libs   # 显示加载器查找库时使用的路径的顺序

export LD_DEBUG=versions  # 版本依赖性

export LD_DEBUG=help  # LD_DEBUG的帮助信息

 

试一下把LD_DEBUG设成以上值之一,再随便运行一个程序试试。

一个试验:

root@vicarious:/home/kamus/projs/horoscope/bins# export LD_DEBUG=libs

root@vicarious:/home/kamus/projs/horoscope/bins# vim my.conf

     24360:   find library=libm.so.6 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libm.so.6

     24360:  

     24360:   find library=libtinfo.so.5 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libtinfo.so.5

     24360:  

     24360:   find library=libselinux.so.1 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libselinux.so.1

     24360:  

     24360:   find library=libacl.so.1 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libacl.so.1

     24360:  

     24360:   find library=libgpm.so.2 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/usr/lib/x86_64-linux-gnu/libgpm.so.2

     24360:  

     24360:   find library=libc.so.6 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libc.so.6

     24360:  

     24360:   find library=libdl.so.2 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libdl.so.2

     24360:  

     24360:   find library=libattr.so.1 [0]; searching

     24360:   search cache=/etc/ld.so.cache

     24360:     trying file=/lib/x86_64-linux-gnu/libattr.so.1

copyright blog.ykyi.net

为什么dump生成core文件大小是0

今天程序崩溃了,但是生成的core文件大小是0.

用ulimit -c 查看生成core文件的大小限制是无限unlimited.

也不是磁盘大小和写入权限的问题。

但究竟是什么问题呢?

捣了半天终于搞明白,原来是文件系统造成的。

我是在vmware的虚拟机的debian linux上运行程序,文件系统用的是从host机windows 7挂载到/mnt/hgfs的windows的NTFS文件系统。

后来我把程序转移动linux自己的文件系统,崩溃的时候就生成正常的core dump文件了。

copyright blog.ykyi.net

CDT调试中的追踪点和断点有什么区别。

追踪点(Tracepoint)被当成断点(breakpoint)的一种,但有两个不同点需要注意:

1. 当一个追踪点在一个调试会话中被创建时,它并不种入到二进制代码中,直到用户显式地开始追踪实验。这意味着,创建/修改/删除追踪点并不影响程序,直到追踪真正开始。

2. 简单的创建一个追踪点并不是非常有价值,因为它默认不会收集任何信息。重要的是,把操作(Actions)添加到Tracepoint,这样tracepoint被触发的时候,前面自定义的Action就大有用处了。

来自CDT官网的原文:

Create Tracepoints

Tracepoints are handled as a type of breakpoint. There are two differences to note:

  1. When a tracepoint is created in a debug session, it is not actually planted in the binary code until the user explicitly starts the tracing experiment. This means that creating/modifying/deleting tracepoints does not affect the program until tracing is actually started.
  2. Simply creating a Tracepoint has very limited value as it won't collect any information by default. It is important to add Actions to the Tracepoint to tell it what to do. This will be explained below.

copyright blog.ykyi.net

让eclipse自动生成的注释的时间显示英文,不用中文.

这几天换成用eclipse在windows机器上编写代码,远程运行在linux上,并且在windows机器上远程调试。

新建一个C++类的时候,eclipse/CDT自动生成注释,注释的时间用了中文,并且用的注释风格也不是我想要的。

但我想全部用英文,这个如何解决了。在stackoverflow上找到了答案,并试验成功。

windows -> preferences -> c/c++ -> code style -> code template

在右边的注释模板中编辑File Comment,改成你想要的模式。比如我的:

/*********************************************
 * ${file_name}
 * Author: ${user}
 * Created on: ${date}
 ********************************************/

再在eclipse的安装目录上找到eclipse.ini文件,加入:-Duser.language=en_US

重启eclipse。现在${date}变量生产的日期就是全英文了。

copyright blog.ykyi.net

如何从windows远程调试linux程序。

用gdb在远程linux机器上调试程序实在太不方便了。于是想到用eclipse的GUI调试。下面介绍如何从windows远程调试linux程序。

 

 

 

 

1. 在远程linux上安装gdbserver

 

 

2. windows上安装Cygwin或者MinGW。我用Cygwin编译gdb时遇到问题,用MinGW则通过了。但我想Cygwin应该也是可以的.

 

 

3. sourceforge.net上下载expat工程。这是个分析xml文件的开源库。如果跳过这步,也可以,但是gdb不能分析gdbserver发过来的xml文件。 

 

 

4. expat文件夹, ./configure –enable-shared; make; make install

 

 

5. gdb官网下载gdb源代码,解开后运行: ./configure –with-expat –target=x86_64-linux-gnu  –host=i686-pc-mingw32   注意这里的with-expat使得gdb能用解析xml文件的功能,target使得gdb能调试的目标平台的程序,这个字符串可以从l远程inux中运行gdb时开打印出来的声明处得到。Host指定了gdb运行在什么样的平台,这个字符串可以通过运行 ./config.guess 得到。

 

 

6. 然后是make; make install 三板斧。

 

 

7. 现在试一试是否工作正常。在远程linux机器上随便创建一个程序。遵守程序员世界的传统,建个hello world,注意编译时开启 -g 选项。假设源程序是 hello.c, 可执行文件是 hello

 

 

8. 在远程linux端运行 gdbserver :8383 hello 。 8383前有个冒号,8383是端口号,随便取。

 

9. hello.c 和 hello 拷贝到windows机器。

 

 

10. 在控制台介面中,运行 x86_64-linux-gnu-gdb ./Hello。注意前面的gdb名字要相应替换成第5个步骤中编译出来的gdb文件名。

 

11. gdb的控制台交互介面中输入target remote 192.168.44.129:8383 注意把IP换成远程linux机器的IP地址。

12. 试试常用的gdb命令,continue, break, run 什么的。如果能工作就能进入下一步了。

 

13. 创建一个eclipsec/c++工程,源代码则是远程linux机器的源代码.假设工程名也是hello

13. 这一步的目的是在eclipse中创建一个Remote Application Debug configuration。选Run->Debug Configuration在左边选中c/c++ remote application,再点左上角的+号增加一个configuration。在main选项卡的c/c++ application处填windows机上可执行文件hello的路径。Projecteclipsec/c++工程名。 Connection处新建一个连接,类型选linux,其它选项填ssh。我想其它的协议应该也是可以的,但是我用了ssh。 Remote Absolute File path for c/c++ application要填在远程linux机器上启动hello的路径。是否勾上skip download to target path,表示是否在windows机器编译工程然后把编译好的文件上传到远程机器。因为我选择在远程linuxmake,所以我勾选了此项。因你的需求做调整。

 

 

14. Debugger选项卡中把GDB debugger的路填上windows上前面编译出来的gdb的路径。比如我的路径是:D:\MinGW\bin\x86_64-linux-gnu-gdb.exe

 

 

15. 现在就可以用这个Debug configuration远程调试了。

 

 

因为配置远程调试环境涉及到的配置实在太繁杂,如果写一篇考虑所有细节面面俱到的文章太困难了。这篇文章仅把骨干步骤写出,如果读者在实践中遇到各种千奇百怪的问题,需要运用你自己的判断力解决。hope this article helps.

 

copyright blog.ykyi.net