• 在gdb调试时忽略系统信号(signal)

    在gdb调试程序时,默认情况下gdb在收到信号时会中断程序的运行,并将收到的信号显示出来。这时,可以选择输入 c (continue)让程序继续运行。如果程序会重复收到这信号,会非常影响调试效率。可以通过配置忽略指定的系统信号。

    查看当前系统信号的处理信息的指令如下。

    (gdb) info signal
    

    以调试网络程序为例,进程会经常收到 SIGPIPE 消息,对于网络进程的 SIGPIPE 消息在程序中会由自身处理,可以使用以下指令让gdb不再提示 SIGPIPE 信号。

    (gdb) handle SIGPIPE nostop noprint
    

    其中, nostop 表示在收到信号时不再中断程序的运行, noprint 表示在收到信号时不再将收到的信号打印到gdb调试界面,这两个参数可以分开使用。

    参考资料: gnu gdb manual

    (全文完)

  • C++11新特性:基于范围的for循环

    在C++11中,介绍了一种新的for循环写法,基于范围的for循环。
    与旧的for循环类似,也是用来对遍历容器中的所有元素,新的写法更加简洁方便。可以使用auto自动适配容器中的内容。为了遍历容器时提高效率,在访问容器内部时可以声明为元素的引用,进而避免不必要的对象拷贝。示例代码如下(代码节选自 cppreferance

    std::vector<int> v = {0, 1, 2, 3, 4, 5};
    for (const int& i : v) // access by const reference
    {
        std::cout << i << ' ';
    }
    std::cout << '\n';
    
    for (auto i : v) // access by value, the type of i is int
    {
        std::cout << i << ' ';
    }
    std::cout << '\n';
    
    for (int n : {0, 1, 2, 3, 4, 5}) // the initializer may be a braced-init-list
    {
        std::cout << n << ' ';
    }
    std::cout << '\n';
    
    int a[] = {0, 1, 2, 3, 4, 5};
    for (int n : a) // the initializer may be an array
    {
        std::cout << n << ' ';
    }
    std::cout << '\n';
    
    for (int n : a)
    {
        std::cout << 1 << ' '; // the loop variable need not be used
    }
    std::cout << '\n';
    

    注意 std::map 的范围for循环遍历的写法
    std::map 中存放的是 key-value pair 键值对,所以在遍历的时候每次拿到的是一个 pair ,在访问其中的元素时,需要注意书写方法。示例代码如下。

    std::map<int, std::string> mapDemo;
    for (auto& kvp : mapDemo)
    {
        std::cout << kvp.first;
        std::cout << " - ";
        std::cout << kvp.second;
        std::cout << std::endl;
    }
    
  • Linux常用命令行指令 - scp

    scp 命令代表的是 secure copy,与 cp 命令的本地拷贝十分相似,主要区别就在于 scp 的路径可以是一个远程机器的路径。使用 scp 进行文件拷贝时,文件的传输时加密的。

    cp source_path dest_path
    

    从远程机器向本地拷贝

    以下命令会把 host 主机上的 src_path 文件拷贝到本地 dest_path 目录中。

    scp [email protected]:src_path dest_path
    

    从本地向远程机器拷贝

    以下命令会把本地 src_path 的文件拷贝打 host 主机上的 dest_path 路径上。

    scp src_path [email protected]:dest_path
    

    拷贝目录下的所有文件

    可以使用 -r 参数完成目录的递归拷贝, r 代表 recursive 递归。

    scp -r [email protected]:/src_path dest_path
    

    在拷贝时限制带宽

    可以使用 -l 参数限制传输的带宽, l 代表 limit 限制,限制带宽的单位是 kbps
    命令会在将拷贝传输的速度限制为 100kbps。

    scp -l 100 src_path dest_path
    
  • C++11新特性:自动类型推导

    关键字 auto 用于自动类型推导

    auto x=0;     // int
    auto c='a';   // char
    auto d=0.5;   // double
    

    自动类型推导主要用于声明比较复杂的变量,或者变量是在泛型编程(模板)中自动生成出来的。

    vector<int> vecNumbers;
    vector<int>::const_iterator it = vecNumbers.begin();
    auto it = vecNumbers.begin();
    

    auto 类型推导并不会指定 constvolatile 属性

    如果需要限定声明的变量为 constvolatile 属性,需要额外提供相应的关键字限定。因为编译器并不能推断出声明的变量是否具有常值属性和易失属性。

    volatile auto num=5;           // volatile int
    auto volatile const var=true;  //const valatile bool
    auto const ch='a';             // const char
    

    关键字 decltype 用于获取一个对量的类型

    使用 decltype 存储一个对象或表达式的类型, decltype 可以看做是 auto 的补充。

    vector<int> vecNumbers;
    typedef decltype(vecNumbers.begin()) Iterator;
    Iterator it2;
    

    函数返回值类型推导

    在C++11中可以使用 autodecltype 完成函数返回类型的推导。
    旧的函数声明格式 return_type func_name(param_type param, ...);
    新的函数声明格式示例如下,以下函数接收 bool 作为函数的参数,并返回 bool 类型的结果。

    auto func_name(bool bParam)->decltype(bParam)
    {
      return bParam;
    }
    

    函数返回值类型推导在模板泛型编程中非常有用,模板函数能够定义一个通用的返回类型,返回值类型会根据 decltype 自动推导。
    新的函数声明格式更易于维护,因为返回值并没有作为硬编码写入源文件中,但这样做可能会牺牲代码的可读性。

    template <class T>
    auto get_end(vector<T>& v) -> decltype(v.end())
    {
      return v.end();
    }
    
    vector<int> vecNumbers;
    auto it = get_end(vecNumbers);      // returns iterator
    
    const vector<int> vecNumbers2;
    auto it2 = get_enm(vecNumbers2);    // returns const_iterator
    
  • Linux下的FIFO、pipe、unix domain socket漫谈

    在做Linux开发时,经常会接触 管道AF_UNIX 等相关词汇,为了弄清他们之间的关系,查阅了一些资料,将结果整理并记录下来。

  • Linux下使用gdb的调试技巧(2)

    本文重点介绍在gdb模式下的常用命令。