【问题标题】:printing ip addresses using gdb使用 gdb 打印 IP 地址
【发布时间】:2010-12-21 11:00:11
【问题描述】:

我正在调试网络代码并希望打印声明为int32 的IP 地址。 当我使用 gdb print 命令打印它时,我得到一些没有多大意义的值。

我怎样才能以有意义的格式打印它们?

【问题讨论】:

    标签: c++ printing gdb ip-address


    【解决方案1】:

    就这样使用inet_ntoa(3)

    (gdb) p (char*)inet_ntoa(0x01234567)  # Replace with your IP address
    $1 = 0xa000b660 "103.69.35.1"
    

    【讨论】:

    • IPv6 地址是否有类似的可能?
    • 我怀疑这一点,甚至在询问之前尝试过,但我提供什么作为第三个参数?我尝试了不同的方法,但我总是得到 SIGSEGV。
    • 你需要在下级进程的地址空间中传递一个地址。您可以在某处获取一些未使用的全局缓冲区,或者您可以自己 malloc 它,例如(gdb) p (void*)malloc(64); $1 = (void *) 0x12345678; (gdb) p (char*)inet_ntop(23,&my_ip6_addr,0x12345678,64).
    【解决方案2】:

    如果您正在调试核心文件并且无法使用 inet_ntoa(),那么您也可以执行以下操作:

    (gdb) 设置 $int_ip = 0x01234567 (gdb) printf "%d.%d.%d.%d\n", ($int_ip & 0xff), ($int_ip >> 8) & 0xff, ($int_ip >> 16) & 0xff, ($int_ip >> 24) 103.69.35.1 (gdb)

    【讨论】:

      【解决方案3】:

      但是 inet_ntoa() 不采用 u_int32_t 参数,而是采用 struct in_addr 参数,所以之前的答案: p (char *)inet_ntoa(3) 我觉得不对。

      这是一种在名为 gdb.cmd.txt 的文件中定义函数的方法,因此在启动时调用“gdb -x gdb.cmd.txt”。

      在 gdb.cmd.txt 中,放这个:

      define ntoa
              set $ipv4 = $arg0
              echo IPV4 =.
              p $ipv4
              set $val1 = ($ipv4 >> 24) & 0xff
              set $val2 = ($ipv4 >> 16) & 0xff
              set $val3 = ($ipv4 >>  8) & 0xff
              set $val4 = ($ipv4 >>  0) & 0xff
             printf "IPV4=%u=0x%02x.%02x.%02x.%02x =%d.%d.%d.%d\n", $ipv4, $val1, $val2, $val3, $val4, $val1, $val2, $val3, $val4
          end
      

      然后运行gdb,调用ntoa“用户定义函数”如下:

      (gdb) ntoa(0x01020304)
      IPV4 =.$10 = 16909060
      IPV4=16909060=0x01.02.03.04 =1.2.3.4
      (gdb) ntoa(-1)
      IPV4 =.$10 = -1
      IPV4=4294967295=0xff.ff.ff.ff =255.255.255.255
      

      顺便说一句:我现在正在搜索 gdb 中是否有方法让函数返回格式化字符串,以便我可以运行命令“p ntoa(0x01020304)”或“p ntoa(ptr->ipv4_addresss)”(假设 ptr 是包含 u_int32_t ipv4_address" 数据元素的结构的有效 ptr)。但似乎 gdb 用户定义的函数不允许 sprintf() 调用。

      -dennis Bednar 2012 年 12 月

      【讨论】:

      • 请注意,此答案将在 x86 等小端系统上向后打印您的 IP 地址。在这些体系结构中,网络字节顺序地址(例如通常提供给 inet_ntoa 的地址)将与第一个八位字节一起存储在最低有效字节中。
      【解决方案4】:

      解释 Gopinath 的回应:

      (gdb) p/uc (char[4]) 342757386
      $4 = {10 '\n', 16 '\020', 110 'n', 20 '\024'}
      

      p/uc:告诉 gdb 将数据视为无符号字符内容。

      (char[4]) 342757386:将 IP 转换为 4 个字符元素的数组,每个元素代表一个字节/八位字节。

      所以您告诉 gdb 将 IP 的十进制表示视为四个字节的数组 - 四个八位字节 - 然后将它们打印为无符号字符。

      如果忽略每个字节的 ASCII 表示,则您的 IP 地址为:10.16.110.20

      【讨论】:

        【解决方案5】:

        创建一个调用inet_ntoa的函数,然后在你的int上用gdb中的'p'命令调用它。

        【讨论】:

          【解决方案6】:

          这是另一种有趣的方式:

          #include <sys/types.h>  // u_int32_t
          
          
          // next 3 for inet_ntoa() call
          #include <sys/socket.h>
          #include <netinet/in.h>
          #include <arpa/inet.h>
          
          // C++ headers
          #include <iostream> // std::cout
          #include <string>
          #include <sstream>  // ostringstream
          
          
          // class to aid in using the gdb(3) debugger to print a u_int32_t ip_address as a string.
          // The toString() is a static method!!
          // How to call a C++ method from the gdb debugger, to simulate the inet_nto(3) method
          //
          // From within gdb debugger, you must have a process, so first stop at main:
          //  b main
          //  r
          //
          //  (gdb) p MYIP4::toString(0x0fffefdfc)
          //  $1 = "255.254.253.252"
          //
          //  (gdb) p MYIP4::toString(-1)
          //  $2 = "255.255.255.255"
          //
          //  (gdb) p MYIP4::toString(65536)
          //  $3 = "0.1.0.0"
          //
          // Drawbacks: the a.out executable that you are debugging needs the MYIP4 class already
          // compiled and linked into the executable that you are debugging.
          //
          // PS: I don't know if there is a "slick way" where the MyIP4 class could dynamically be loaded,
          // within gdb(), if the executable failed to contain the MYIP4 class.
          //
          // PS: I had trouble with my operator() idea.. If you know how to improve on it, post away!
          //
          // @author 1201207 dpb  created
          //=============================
          
          class MYIP4
          {
          public:
              static std::string toString(u_int32_t ipv4_address )
              {
                  struct in_addr temp_addr;
          
                  // inet_ntoa() returns a char * to a buffer which may be overwritten
                  // soon, so convert char* to a string for extra safety.
                  temp_addr.s_addr = htonl(ipv4_address);
                  std::string ipv4String = std::string(inet_ntoa( temp_addr ));
                  return ipv4String;
              }
          
          #if 0
              // this idea did NOT work, so it is commented out.
              //
              // overload the () operator, so that, within gdb, we can simply type:
              //  p MYIP4(0x01020304)
              // instead of:
              //  p MYIP4::toString(0x01020304)
          
              std::string operator() ( u_int32_t ipv4_address )
              {
                  return toString(ipv4_address);
              }
          #endif
          
          };
          
          
          void test1();
          
          int main()
          {
              test1();
              return 0;
          }
          
          void test1()
          {
              u_int32_t   ipv4Address = 0x01020304;   // host byte order for 1.2.3.4
              std::cout << "Test1: IPAddress=" << MYIP4::toString(ipv4Address) << "\n";
          }
          

          【讨论】:

            【解决方案7】:

            试试这个命令:

            (gdb) p/uc (char[4])342757386
            $1 = {10 '\n', 16 '\020', 110 'n', 20 '\024'}
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-10-16
              • 1970-01-01
              • 2018-07-04
              • 2014-01-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多