现实数组:

比如说要显示a[10]中全部的内容
用 p a显示的是地址,用p *a显示的是第一个元素
显示全部或某一个:
p (int [10])*a
或者
p *a@10

如果你使用 p *a@3 或 p *&a[0]@3 将打印从数组中从a[0]开始的3个值。如果数组元素很多比如1000个,而你想打印a[600]开始的7个,可以使用 p *&a[600]@7。

8 gdb tricks you should know

By Ksplice Post Importer on Jan 24, 2011

Despite its age, gdb remains an amazingly versatile and flexible tool, and mastering it can save you huge amounts of time when trying to debug problems in your code. In this post, I'll share 10 tips and tricks for using GDB to debug most efficiently.

I'll be using the Linux kernel for examples throughout this post, not because these examples are necessarily realistic, but because it's a large C codebase that I know and that anyone can download and take a look at. Don't worry if you aren't familiar with Linux's source in particular -- the details of the examples won't matter too much.

  1. break WHERE if COND

    If you've ever used gdb, you almost certainly know about the "breakpoint" command, which lets you break at some specified point in the debugged program.

    But did you know that you can set conditional breakpoints? If you add if CONDITION to a breakpoint command, you can include an expression to be evaluated whenever the program reaches that point, and the program will only be stopped if the condition is fulfilled. Suppose I was debugging the Linux kernel and wanted to stop whenever init got scheduled. I could do:

    1. (gdb) break context_switch if next == init_task

    Note that the condition is evaluated by gdb, not by the debugged program, so you still pay the cost of the target stopping and switching to gdb every time the breakpoint is hit. As such, they still slow the target down in relation to to how often the target location is hit, not how often the condition is met.

  2. command

    In addition to conditional breakpoints, the command command lets you specify commands to be run every time you hit a breakpoint. This can be used for a number of things, but one of the most basic is to augment points in a program to include debug output, without having to recompile and restart the program. I could get a minimal log of every mmap() operation performed on a system using:

    1. (gdb) b do_mmap_pgoff
    2. Breakpoint 1 at 0xffffffff8111a441: file mm/mmap.c, line 940.
    3. (gdb) command 1
    4. Type commands for when breakpoint 1 is hit, one per line.
    5. End with a line saying just "end".
    6. >print addr
    7. >print len
    8. >print prot
    9. >end
    10. (gdb)
  3. gdb --args

    This one is simple, but a huge timesaver if you didn't know it. If you just want to start a program under gdb, passing some arguments on the command line, you can just build your command-line like usual, and then put "gdb --args" in front to launch gdb with the target program and the argument list both set:

    1. [~]$ gdb --args pizzamaker --deep-dish --toppings=pepperoni
    2. ...
    3. (gdb) show args
    4. Argument list to give program being debugged when it is started is
    5. " --deep-dish --toppings=pepperoni".
    6. (gdb) b main
    7. Breakpoint 1 at 0x45467c: file oven.c, line 123.
    8. (gdb) run
    9. ...

    I find this especially useful if I want to debug a project that has some arcane wrapper script that assembles lots of environment variables and possibly arguments before launching the actual binary (I'm looking at you, libtool). Instead of trying to replicate all that state and then launch gdb, simply make a copy of the wrapper, find the final "exec" call or similar, and add "gdb --args" in front.

  4. Finding source files

    I run Ubuntu, so I can download debug symbols for most of the packages on my system from ddebs.ubuntu.com, and I can get source using apt-get source. But how do I tell gdb to put the two together? If the debug symbols include relative paths, I can use gdb's directory command to add the source directory to my source path:

    1. [~/src]$ apt-get source coreutils
    2. [~/src]$ sudo apt-get install coreutils-dbgsym
    3. [~/src]$ gdb /bin/ls
    4. GNU gdb (GDB) 7.1-ubuntu
    5. (gdb) list main
    6. 1192 ls.c: No such file or directory.
    7. in ls.c
    8. (gdb) directory ~/src/coreutils-7.4/src/
    9. Source directories searched: /home/nelhage/src/coreutils-7.4:$cdir:$cwd
    10. (gdb) list main
    11. 1192 }
    12. 1193 }
    13. 1194
    14. 1195 int
    15. 1196 main (int argc, char **argv)
    16. 1197 {
    17. 1198 int i;
    18. 1199 struct pending *thispend;
    19. 1200 int n_files;
    20. 1201

    Sometimes, however, debug symbols end up with absolute paths, such as the kernel's. In that case, I can use set substitute-path to tell gdb how to translate paths:

    1. [~/src]$ apt-get source linux-image-2.6.32-25-generic
    2. [~/src]$ sudo apt-get install linux-image-2.6.32-25-generic-dbgsym
    3. [~/src]$ gdb /usr/lib/debug/boot/vmlinux-2.6.32-25-generic
    4. (gdb) list schedule
    5. 5519 /build/buildd/linux-2.6.32/kernel/sched.c: No such file or directory.
    6. in /build/buildd/linux-2.6.32/kernel/sched.c
    7. (gdb) set substitute-path /build/buildd/linux-2.6.32 /home/nelhage/src/linux-2.6.32/
    8. (gdb) list schedule
    9. 5519
    10. 5520 static void put_prev_task(struct rq *rq, struct task_struct *p)
    11. 5521 {
    12. 5522 u64 runtime = p->se.sum_exec_runtime - p->se.prev_sum_exec_runtime;
    13. 5523
    14. 5524 update_avg(&p->se.avg_running, runtime);
    15. 5525
    16. 5526 if (p->state == TASK_RUNNING) {
    17. 5527 /*
    18. 5528 * In order to avoid avg_overlap growing stale when we are
  5. Debugging macros

    One of the standard reasons almost everyone will tell you to prefer inline functions over macros is that debuggers tend to be better at dealing with inline functions. And in fact, by default, gdb doesn't know anything at all about macros, even when your project was built with debug symbols:

    1. (gdb) p GFP_ATOMIC
    2. No symbol "GFP_ATOMIC" in current context.
    3. (gdb) p task_is_stopped(&init_task)
    4. No symbol "task_is_stopped" in current context.

    However, if you're willing to tell GCC to generate debug symbols specifically optimized for gdb, using -ggdb3, it can preserve this information:

    1. $ make KCFLAGS=-ggdb3
    2. ...
    3. (gdb) break schedule
    4. (gdb) continue
    5. (gdb) p/x GFP_ATOMIC
    6. $1 = 0x20
    7. (gdb) p task_is_stopped_or_traced(init_task)
    8. $2 = 0

    You can also use the macro and info macro commands to work with macros from inside your gdb session:

    1. (gdb) macro expand task_is_stopped_or_traced(init_task)
    2. expands to: ((init_task->state & (4 | 8)) != 0)
    3. (gdb) info macro task_is_stopped_or_traced
    4. Defined at include/linux/sched.h:218
    5. included at include/linux/nmi.h:7
    6. included at kernel/sched.c:31
    7. #define task_is_stopped_or_traced(task) ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)

    Note that gdb actually knows which contexts macros are and aren't visible, so when you have the program stopped inside some function, you can only access macros visible at that point. (You can see that the "included at" lines above show you through exactly what path the macro is visible).

  6. gdb variables

    Whenever you print a variable in gdb, it prints this weird $NN = before it in the output:

    1. (gdb) p 5+5
    2. $1 = 10

    This is actually a gdb variable, that you can use to reference that same variable any time later in your session:

    1. (gdb) p $1
    2. $2 = 10

    You can also assign your own variables for convenience, using set:

    1. (gdb) set $foo = 4
    2. (gdb) p $foo
    3. $3 = 4

    This can be useful to grab a reference to some complex expression or similar that you'll be referencing many times, or, for example, for simplicity in writing a conditional breakpoint (see tip 1).

  7. Register variables

    In addition to the numeric variables, and any variables you define, gdb exposes your machine's registers as pseudo-variables, including some cross-architecture aliases for common ones, like $sp for the the stack pointer, or $pc for the program counter or instruction pointer.

    These are most useful when debugging assembly code or code without debugging symbols. Combined with a knowledge of your machine's calling convention, for example, you can use these to inspect function parameters:

    1. (gdb) break write if $rsi == 2

    will break on all writes to stderr on amd64, where the $rsi register is used to pass the first parameter.

  8. The x command

    Most people who've used gdb know about the print or p command, because of its obvious name, but I've been surprised how many don't know about the power of the x command.

    x (for "examine") is used to output regions of memory in various formats. It takes two arguments in a slightly unusual syntax:

    1. x/FMT ADDRESS

    ADDRESS, unsurprisingly, is the address to examine; It can be an arbitrary expression, like the argument to print.

    FMT controls how the memory should be dumped, and consists of (up to) three components:

    • A numeric COUNT of how many elements to dump
    • A single-character FORMAT, indicating how to interpret and display each element
    • A single-character SIZE, indicating the size of each element to display.

    x displays COUNT elements of length SIZE each, starting from ADDRESS, formatting them according to the FORMAT.

    There are many valid "format" arguments; help x in gdb will give you the full list, so here's my favorites:

    x/x displays elements in hex, x/d displays them as signed decimals, x/c displays characters, x/i disassembles memory as instructions, and x/s interprets memory as C strings.

    The SIZE argument can be one of: b, h, w, and g, for one-, two-, four-, and eight-byte blocks, respectively.

    If you have debug symbols so that GDB knows the types of everything you might want to inspect, p is usually a better choice, but if not, x is invaluable for taking a look at memory.

    1. [~]$ grep saved_command /proc/kallsyms
    2. ffffffff81946000 B saved_command_line
    3. (gdb) x/s 0xffffffff81946000
    4. ffffffff81946000 <>: "root=/dev/sda1 quiet"

    x/i is invaluable as a quick way to disassemble memory:

    1. (gdb) x/5i schedule
    2. 0xffffffff8154804a <schedule>: push %rbp
    3. 0xffffffff8154804b <schedule+1>: mov $0x11ac0,%rdx
    4. 0xffffffff81548052 <schedule+8>: mov %gs:0xb588,%rax
    5. 0xffffffff8154805b <schedule+17>: mov %rsp,%rbp
    6. 0xffffffff8154805e <schedule+20>: push %r15

    If I'm stopped at a segfault in unknown code, one of the first things I try is something like x/20i $ip-40, to get a look at what the code I'm stopped at looks like.

    A quick-and-dirty but surprisingly effective way to debug memory leaks is to let the leak grow until it consumes most of a program's memory, and then attach gdb and just x random pieces of memory. Since the leaked data is using up most of memory, you'll usually hit it pretty quickly, and can try to interpret what it must have come from.

gdb 技巧的更多相关文章

  1. GDB技巧整理

    https://blog.atime.me/note/gdb-tricks.html 整理常用的gdb技巧. 常用命令 常用的gdb命令... 启动gdb 直接运行 gdb --args prog a ...

  2. Linux之实用GDB技巧

    一.引言 在Linux下开发,肯定少不了与gdb打交道,而gdb的命令又非常多,有些是不常用的但是特殊情况下却是必须的,因此记录在此,以便翻阅 二.基本命令 前面是命令全名,在不混淆的情况下,可以简写 ...

  3. GDB技巧:使用终端界面模式

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 简 ...

  4. gdb 调试多线程

    基本i threads 等操作略过,只谈线程同步.异步控制: 先点到,gdb attach到主线程t1 时,所有线程都会停止,所谓同步异步效果,是指在apply continue到所有线程之后, 再切 ...

  5. linux内核调试指南

    linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 ...

  6. C 语言资源大全中文版

    C 语言资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理.awesome-c 是 koz.ross 发起维护的 C 语言资源列表,内容包括了: ...

  7. # 20145314《信息安全系统设计基础》期中复习总结 Part B

    20145314<信息安全系统设计基础>期中复习总结 Part B 学习知识点内容总结 复习线索:http://group.cnblogs.com/topic/73069.html 本周的 ...

  8. Linux Kernel - Debug Guide (Linux内核调试指南 )

    http://blog.csdn.net/blizmax6/article/details/6747601 linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级 ...

  9. 【转贴】gdb中的信号(signal)相关调试技巧

    一篇不错的帖子,讲的是gdb中的信号(signal)相关调试技巧 转自Magic C++论坛  http://www.magicunix.com/index_ch.html  http://www.m ...

随机推荐

  1. java对称加密报错:Input length must be multiple of 8 when decrypting with padded cipher

    HTTP Status 500 - Request processing failed; nested exception is javax.crypto.IllegalBlockSizeExcept ...

  2. 利用 java.lang.Runtime.addShutdownHook() 钩子程序,保证java程序安全退出

    以前在开发时只知道依靠数据库事务来保证程序关闭时数据的完整性. 但有些时候一个业务上要求的原子操作,不一定只包括数据库,比如外部接口或者消息队列.此时数据库事务就无能为力了. 这时我们可以依靠java ...

  3. ubuntu10.04开启root登陆

    半年没有用ubuntu了,以前用的是8.10,现在装了一个10.04,第一印象就是登陆窗口变了,哎,比较喜欢用root用户登录系统,不喜欢非root用户,做任何事都要来一下sudo,10.04的登陆窗 ...

  4. Web内容管理系统 Magnolia 安装使用-挖掘优良的架构(2)

    在Windows上安装社区版  tomcat集成版 Magnolia CMS社区版本为免费发行,不需要任何GNU通用公共许可协议(第3版)条款下的授权(这个许可协议允许您在特定条款和条件下,重新分配和 ...

  5. JS创建类以及类的方法(StringBuffeer类)

    创建StringBuffer类以及toString,append()方法 //创建一个StringBuffer类 ,此类有两个方法:一个是append方法一个是toString方法 function ...

  6. Codeforces Round #204 (Div. 2) C

    写了一记忆化 TLE了  把double换成long long就过了 double 这么耗时间啊 #include <iostream> #include<cstdio> #i ...

  7. poj 2029 Get Many Persimmon Trees (dp)

    题目链接 又是一道完全自己想出来的dp题. 题意:一个w*h的图中,有n个点,给一个s*t的圈,求这个圈能 圈的最多的点 分析:d[i][j]代表i行j列 到第一行第一列的这个方框内有多少个点, 然后 ...

  8. android上的缓存、缓存算法和缓存框架

      1.使用缓存的目的 缓存是存取数据的临时地,因为取原始数据代价太大了,加了缓存,可以取得快些.缓存可以认为是原始数据的子集,它是从原始数据里复制出来的,并且为了能被取回,被加上了标志. 在andr ...

  9. C#中结构体的声明

    定义:       结构是用户自定义的值类型 代码样式:struct Pair{    public int X, Y; //公有变量名单词的首字母大写(PascalCase规则)}struct Pa ...

  10. hdu 4690 EBCDIC

    还有什么好说的呢?打表题= = #include<cstdio> #include<cstring> #include<algorithm> #include< ...