GDB使用記錄

本文來自個人博客 sunyongfeng.com。博客的文章保持更新,此文可能不是最新狀態(tài)毫目。

簡介

GDB,GNU Debugger诲侮,特性如下:

  • GDB具備各種調(diào)試功效镀虐,可對計算機程序的運行進行追蹤、警告沟绪。使用者可以監(jiān)控及修改程序內(nèi)部變量的值刮便,甚至可在程序的正常運行之外調(diào)用函數(shù)。
  • GDB支持多數(shù)處理器架構(gòu)
  • 持續(xù)開發(fā)中
  • 支持遠程調(diào)試
  • 支持內(nèi)核調(diào)試绽慈,KGDB

從事嵌入式軟件開發(fā)兩年來恨旱,主要在以下幾方面使用GDB:

  1. 查看、修改運行時變量坝疼;
  2. 多線程調(diào)試搜贤,查看當前線程運行狀態(tài)(以確定當前線程是不是因為等鎖等原因掛起);
  3. 查看coredump文件钝凶;
  4. 碰到難纏的內(nèi)存非法改寫問題仪芒,用GDB的斷點、物理watch功能查看內(nèi)存變化以定位改寫者;

引用公司一個技術(shù)牛人的話:在大型的項目中桌硫,使用GDB的單步調(diào)試夭咬、軟件watch是不現(xiàn)實的,因為會運行得實在太慢铆隘。

命令小記:

linux提示符
1. GDB進入正在運行的進程
    gdb 可執(zhí)行文件 core文件 
    gdb -p pid
    
GDB提示符
1. 查看調(diào)用棧信息
    bt / backtrace / bt full
    frame n
    info locals
    info args

2. 查看卓舵、設(shè)置變量
    p 變量
    p 變量 = 新值
    set 變量 = 新值
    
3. 查看內(nèi)存
    x/<n/f/u> <addr>

4. 線程調(diào)試
    info thread
    thread n

啟動GDB

GCC選項###

想用GDB調(diào)試,則在GCC編譯的時候要加上-g選項膀钠。

啟動GDB

啟動GDB的方法主要有以下幾種:

  • gdb
  • gdb executable_file
  • gdb executable_file corefile:查看coredump文件信息掏湾,定位coredump產(chǎn)生原因、觸發(fā)源肿嘲。
  • gdb attach pid:調(diào)度運行時的進程或線程融击,同gdb -p pid

善用help

在GDB提示符下輸入helphelp 命令雳窟,能夠查看命令的幫助說明尊浪。

(gdb) help
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.

查看調(diào)用棧

寫一個簡單的例子(僅為樣例,并不嚴謹):

#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <assert.h>
#include <sys/prctl.h>

typedef struct {
    int member_a;
    int member_b;
} test_t;

int g_int;
bool g_bool;
char *g_str[] = {
    "Hello, GDB!",
    "It's funny."
};

void stay_here(int arg, test_t *test)
{
    int local;

    local = 100;
    while (true) {
        local++;
        if (local % 200 == 0) {
            local = 0;
        }
        sleep(1);
    }

    return;
}

void *thread_process(void *arg)
{
    int in;
    char name[64];

    in = (int)arg;
    (void)snprintf(name, 64, "test-%d", in + 1);
    prctl(PR_SET_NAME, (unsigned long)name);  /* set thread name */

    while (true) {
        sleep(2);
    }

    return NULL;
}

void create_thread(void)
{
    int i, rv;
    pthread_t tid;

    for (i = 0; i < 5; i++) {
        rv = pthread_create(&tid, NULL, thread_process, (void *)i);
        assert(rv == 0);
    }
}

int main(int argc, char **argv)
{
    int local;
    test_t test;

    local = 999;
    test.member_a = 10;
    test.member_b = 11;

    create_thread();
    stay_here(local, &test);

    return 0;
}

編譯并運行起來封救,注意gcc的-g選項拇涤,這里使用&讓程序運行到后臺,[1] 8043指剛剛這個程序運行時的進程號誉结,也可用ps命令查看鹅士。

sunnogo@a3e420:~/test/gdb$ gcc -o prt_mod_var prt_mod_var.c -g -Wall -lpthread
sunnogo@a3e420:~/test/gdb$ 
sunnogo@a3e420:~/test/gdb$ ls
prt_mod_var  prt_mod_var.c
sunnogo@a3e420:~/test/gdb$ ./prt_mod_var &
[1] 8043
sunnogo@a3e420:~/test/gdb$ 
sunnogo@a3e420:~/test/gdb$ ps -e | grep prt_mod_var
 8043 pts/1    00:00:00 prt_mod_var

接下來使用gdb -p 8043連入正在運行的進程中。還不明白為什么我的計算機中要求使用root權(quán)限才能讓GDB attach到對應(yīng)進程惩坑。

sunnogo@a3e420:~/test/gdb$ gdb -p 8043
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Attaching to process 8043
Could not attach to process.  If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user.  For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.
(gdb) quit

重新sudo gdb -p pid進入進程掉盅。

  • 使用bt查看當前調(diào)用棧信息(call stack,即函數(shù)調(diào)用層次信息)以舒,當前進程的是由main() -> sleep() -> nanosleep() -> __kernel_vsyscall()一層一層調(diào)入趾痘。注意“#數(shù)字”,在GDB中這叫stack frames蔓钟,或直接稱為frame永票,運行棧由一個或多個連續(xù)的frame組成,數(shù)字越小代表調(diào)用層次越深奋刽。
  • 使用bt full查看詳細調(diào)用棧信息瓦侮,會把各個frame的入?yún)⒑途植孔兞啃畔@示出來艰赞。這里bt是backtrace的縮寫佣谐,GDB的全命令經(jīng)常有其簡短的寫法。

注意:GDB中方妖,按回車默認是執(zhí)行上一次命令狭魂。
先MARK下面的“No symbol table info available.

sunnogo@a3e420:~/test/gdb$ sudo gdb -p 8043
[sudo] password for sunnogo: 
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Attaching to process 8043
Reading symbols from /home/sunnogo/test/gdb/prt_mod_var...done.
Reading symbols from /lib/i386-linux-gnu/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/i386-linux-gnu/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
0xb7751424 in __kernel_vsyscall ()
(gdb) bt 
#0  0xb7751424 in __kernel_vsyscall ()
#1  0xb7640ce0 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
#2  0xb7640aff in sleep () from /lib/i386-linux-gnu/libc.so.6
#3  0x0804845b in stay_here (arg=999, test=0xbf8e5118) at prt_mod_var.c:26
#4  0x08048492 in main (argc=1, argv=0xbf8e51c4) at prt_mod_var.c:41
(gdb) bt full
#0  0xb7751424 in __kernel_vsyscall ()
No symbol table info available.
#1  0xb7640ce0 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
#2  0xb7640aff in sleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
#3  0x0804845b in stay_here (arg=999, test=0xbf8e5118) at prt_mod_var.c:26
        local = 113
#4  0x08048492 in main (argc=1, argv=0xbf8e51c4) at prt_mod_var.c:41
        local = 999
        test = {member_a = 10, member_b = 11}
  • 使用frame n進入“#n”的frame。默認顯示當前函數(shù)名、函數(shù)入?yún)⒋瞥巍斍斑\行處所在源文件的代碼行位置斋泄,并顯示當前行代碼。
  • 使用info命令查看frame詳細信息镐牺,info命令不是全命令炫掐,后面還有子命令。info有很多子命令睬涧,除本frame外募胃,還可以查看本進程信息、系統(tǒng)信息畦浓,這里僅僅是冰山一角痹束。
    • info frame 顯示當前frame信息
    • info args 顯示入?yún)⑿畔?/li>
    • info local 顯示局部變量信息
(gdb) frame 3
#3  0x0804845b in stay_here (arg=999, test=0xbf8e5118) at prt_mod_var.c:26
26              sleep(1);
(gdb) info frame
Stack level 3, frame at 0xbf8e5100:
 eip = 0x804845b in stay_here (prt_mod_var.c:26); saved eip 0x8048492
 called by frame at 0xbf8e5130, caller of frame at 0xbf8e50d0
 source language c.
 Arglist at 0xbf8e50f8, args: arg=999, test=0xbf8e5118
 Locals at 0xbf8e50f8, Previous frame's sp is 0xbf8e5100
 Saved registers:
  ebx at 0xbf8e50f4, ebp at 0xbf8e50f8, eip at 0xbf8e50fc
(gdb) info args
arg = 999
test = 0xbf8e5118
(gdb) info local
local = 113
(gdb) 

查看、修改變量

p var查看變量信息讶请,p是print的縮寫祷嘶。

  • p var
  • p *(指針類型)地址
  • p *結(jié)構(gòu)體指針
  • p 數(shù)組名
# 打印變量 
(gdb) p g_int
$3 = 0
(gdb) p g_bool
$4 = false

# 打印特定類型指針
(gdb) info local
local = 113
(gdb) p &local
$11 = (int *) 0xbf8e50ec
(gdb) p *(int *) 0xbf8e50ec
$12 = 113
(gdb) 

# 打印結(jié)構(gòu)體指針
(gdb) p test
$1 = (test_t *) 0xbf8e5118
(gdb) p *test
$2 = {member_a = 10, member_b = 11}

# 打印數(shù)組名
(gdb) p g_str
$5 = {0x8048538 "Hello, GDB!", 0x8048544 "It's funny."}
(gdb) p g_str[0]
$6 = 0x8048538 "Hello, GDB!"

print不僅可以用來查看變量,還可用于設(shè)置變量夺溢。print var=value论巍。
設(shè)置變量值的命令還有setset var=value企垦。

# set int
(gdb) print local
$1 = 109
(gdb) print local=20
$2 = 20
(gdb) print local
$3 = 20
(gdb) set local=30
(gdb) print local
$4 = 30

# set bool
(gdb) print g_bool
$5 = false
(gdb) set g_bool=true
No symbol "true" in current context.
(gdb) set g_bool=1
(gdb) print g_bool
$6 = true

# set pointer
(gdb) print g_str
$7 = {0x8048538 "Hello, GDB!", 0x8048544 "It's funny."}
(gdb) set g_str[0]="SETTING VAR"
(gdb) print g_str
$8 = {0x8e05008 "SETTING VAR", 0x8048544 "It's funny."}
(gdb) 

查看內(nèi)存

examine查看內(nèi)存环壤,縮寫是x。命令格式:

x/<n/f/u> <addr>

n钞诡、f擅威、u是可選參數(shù),說明如下:

(gdb) help x
Examine memory: x/FMT ADDRESS.
ADDRESS is an expression for the memory address to examine.
FMT is a repeat count followed by a format letter and a size letter.
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
  t(binary), f(float), a(address), i(instruction), c(char) and s(string).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).
The specified number of objects of the specified size are printed
according to the format.

Defaults for format and size letters are those previously used.
Default count is 1.  Default address is following last thing printed
with this command or "print".
  • n表示要打印的多少個單位的內(nèi)存承耿,默認是1及志,單位由u定義;
  • f表示打印的格式朵诫,格式有:
    • o辛友,octal,八進制剪返;
    • x废累,hex,十六進制脱盲;
    • d邑滨,decimal,十進制钱反;
    • u掖看,unsigned decimal匣距,無符號十進制;
    • t哎壳,binary毅待,二進制;
    • f归榕,float尸红;
    • a,address刹泄;
    • i驶乾,instruction,指令循签;
    • c级乐,char,字符县匠;
    • s风科,string,字符串乞旦。
  • u定義單位贼穆,b表示1字節(jié),h表示2字節(jié)兰粉,w表示4字節(jié)故痊,g表示8字節(jié)。
# 當前CPU是intel i3玖姑,小端

# 以十進制形式打印
(gdb) x/8db test
0xbf8e5118:     10      0       0       0       11      0       0       0
(gdb) x/4dh test
0xbf8e5118:     10      0       11      0
(gdb) x/2dw test
0xbf8e5118:     10      11
(gdb) x/2d test
0xbf8e5118:     10      11
(gdb) x/1dg test
0xbf8e5118:     47244640266  # 注意和x/1xg test的結(jié)果比較

# 以二進制形式打印
(gdb) x/1tg test
0xbf8e5118:     0000000000000000000000000000101100000000000000000000000000001010
(gdb) x/2tw test
0xbf8e5118:     00000000000000000000000000001010        00000000000000000000000000001011
(gdb) x/4th test
0xbf8e5118:     0000000000001010        0000000000000000        0000000000001011        0000000000000000
(gdb) x/8tb test
0xbf8e5118:     00001010        00000000        00000000        00000000        00001011        0000000000000000        00000000

# 以十六進制形式打印
(gdb) x/8xb test
0xbf8e5118:     0x0a    0x00    0x00    0x00    0x0b    0x00    0x00    0x00
(gdb) x/4xh test
0xbf8e5118:     0x000a  0x0000  0x000b  0x0000
(gdb) x/2xw test
0xbf8e5118:     0x0000000a      0x0000000b
(gdb) x/1xg test
0xbf8e5118:     0x0000000b0000000a

# 打印字符或字符串
(gdb) x/30cb g_str[0]
0x8048538:      72 'H'  101 'e' 108 'l' 108 'l' 111 'o' 44 ','  32 ' '  71 'G'
0x8048540:      68 'D'  66 'B'  33 '!'  0 '\000'        73 'I'  116 't' 39 '\'' 115 's'
0x8048548:      32 ' '  102 'f' 117 'u' 110 'n' 110 'n' 121 'y' 46 '.'  0 '\000'
0x8048550:      1 '\001'        27 '\033'       3 '\003'        59 ';'  56 '8'  0 '\000'
(gdb) x/s g_str[0]
0x8048538:      "Hello, GDB!"

查看線程信息

有兩種方法可以進入線程調(diào)試:

  • 設(shè)置線程名愕秫,用ps查看母進程的線程信息,獲取tid焰络,再啟動GDB進入戴甩;
  • 直接啟動GDB調(diào)試母進程,info thread查看所有線程信息闪彼,獲取到想要的線程的GDB內(nèi)部編號n甜孤,thread n進入線程的調(diào)用棧。

直接獲取畏腕、調(diào)試線程

上面樣例中創(chuàng)建5條線程缴川,并使用prctl函數(shù)為每條線程命名為"test-n"。
這樣可以通過ps -eL | grep test(或者test進程的pid)來查看剛創(chuàng)建的線程的tid描馅。然后gdb -p tid進入線程調(diào)度把夸。這里進入編號為4的線程。

sunnogo@a3e420:~/test/gdb$ gcc -o test test.c -g -Wall -lpthread
sunnogo@a3e420:~/test/gdb$ ./test &
[2] 16427
sunnogo@a3e420:~/test/gdb$ ps -eL | grep test
16427 16427 pts/1    00:00:00 test
16427 16428 pts/1    00:00:00 test-1
16427 16429 pts/1    00:00:00 test-2
16427 16430 pts/1    00:00:00 test-3
16427 16431 pts/1    00:00:00 test-4
16427 16432 pts/1    00:00:00 test-5
sunnogo@a3e420:~/test/gdb$ sudo gdb -p 16431
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Attaching to process 16431

warning: process 16431 is a cloned process
Reading symbols from /home/sunnogo/test/gdb/test...done.
Reading symbols from /lib/i386-linux-gnu/libpthread.so.0...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Loaded symbols for /lib/i386-linux-gnu/libpthread.so.0
Reading symbols from /lib/i386-linux-gnu/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/i386-linux-gnu/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
0xb774f424 in __kernel_vsyscall ()
(gdb) bt full
#0  0xb774f424 in __kernel_vsyscall ()
No symbol table info available.
#1  0xb7623d06 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
#2  0xb7623aff in sleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
#3  0x080485ee in thread_process (arg=0x3) at test.c:46
        in = 3
        name = "test-4", '\000' <repeats 57 times>
#4  0xb771cd4c in start_thread () from /lib/i386-linux-gnu/libpthread.so.0
No symbol table info available.
#5  0xb765abae in clone () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
(gdb) 

間接獲取流昏、調(diào)試線程

注意和上一種方法的對比扎即,相比起來,第一種方法要方便得多况凉。也從側(cè)面看出為每個線程命名的重要性谚鄙。

sunnogo@a3e420:~/test/gdb$ 
nnogo@a3e420:~/test/gdb$ sudo gdb attach 16427
GNU gdb (GDB) 7.5-ubuntu
Copyright (C) 2012 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 "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
attach: No such file or directory.
Attaching to process 16427
Reading symbols from /home/sunnogo/test/gdb/test...done.
Reading symbols from /lib/i386-linux-gnu/libpthread.so.0...(no debugging symbols found)...done.
[New LWP 16432]
[New LWP 16431]
[New LWP 16430]
[New LWP 16429]
[New LWP 16428]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Loaded symbols for /lib/i386-linux-gnu/libpthread.so.0
Reading symbols from /lib/i386-linux-gnu/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/i386-linux-gnu/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux.so.2
0xb774f424 in __kernel_vsyscall ()
(gdb) info thread
  Id   Target Id         Frame 
  6    Thread 0xb7568b40 (LWP 16428) "test-1" 0xb774f424 in __kernel_vsyscall ()
  5    Thread 0xb6d67b40 (LWP 16429) "test-2" 0xb774f424 in __kernel_vsyscall ()
  4    Thread 0xb6566b40 (LWP 16430) "test-3" 0xb774f424 in __kernel_vsyscall ()
  3    Thread 0xb5d65b40 (LWP 16431) "test-4" 0xb774f424 in __kernel_vsyscall ()
  2    Thread 0xb5564b40 (LWP 16432) "test-5" 0xb774f424 in __kernel_vsyscall ()
* 1    Thread 0xb75696c0 (LWP 16427) "test" 0xb774f424 in __kernel_vsyscall ()
(gdb) thread 3
[Switching to thread 3 (Thread 0xb5d65b40 (LWP 16431))]
#0  0xb774f424 in __kernel_vsyscall ()
(gdb) bt full
#0  0xb774f424 in __kernel_vsyscall ()
No symbol table info available.
#1  0xb7623d06 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
#2  0xb7623aff in sleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
#3  0x080485ee in thread_process (arg=0x3) at test.c:46
        in = 3
        name = "test-4", '\000' <repeats 57 times>
#4  0xb771cd4c in start_thread () from /lib/i386-linux-gnu/libpthread.so.0
No symbol table info available.
#5  0xb765abae in clone () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
(gdb) q
A debugging session is active.

        Inferior 1 [process 16427] will be detached.

Quit anyway? (y or n) y
Detaching from program: /home/sunnogo/test/gdb/test, process 16427
sunnogo@a3e420:~/test/gdb$ 
sunnogo@a3e420:~/test/gdb$ 

gdb中調(diào)用調(diào)用函數(shù)

call func_name(param1, param2, ...),目前還沒有明白如果參數(shù)是結(jié)構(gòu)體要怎么整刁绒。注意闷营,只能在進程上下文中才能使用,coredump中無法使用知市。

gdb中申請內(nèi)存

p malloc(size)傻盟,結(jié)果會返回一個指針,即可正常使用這個指針嫂丙。注意娘赴,只能在進程上下文中才能使用,coredump中無法使用跟啤。如下例:

(gdb) p malloc(4)
[New Thread 0x693ff460 (LWP 2033)]
[Switching to Thread 0xb6101000 (LWP 1456)]
$1 = (void *) 0xb58d01e0    <----使用這個返回的指針诽表。

查看寄存器信息

to-do

GDB反匯編

to-do

斷點設(shè)置

to-do

內(nèi)存監(jiān)控

to-do

GCC選項對GDB的影響

GCC -g選項的影響

注意上面的,如果gcc編譯的時候不加-g選項隅肥,那么frame 3也會顯示“No symbol table info available.”竿奏,無符號表信息可用,全局變量g_str也打不出來腥放。

(gdb) bt full
#0  0xb77a3424 in __kernel_vsyscall ()
No symbol table info available.
#1  0xb7692ce0 in nanosleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
#2  0xb7692aff in sleep () from /lib/i386-linux-gnu/libc.so.6
No symbol table info available.
#3  0x08048462 in main ()
No symbol table info available.
(gdb) p g_str
$1 = 134513928
(gdb) p g_str[0]
cannot subscript something of type `<data variable, no debug info>'
(gdb) p g_bool
$2 = 0
(gdb) 

GCC -fomit-frame-pointer選項的影響

to-do

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泛啸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子秃症,更是在濱河造成了極大的恐慌候址,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件种柑,死亡現(xiàn)場離奇詭異宗雇,居然都是意外死亡,警方通過查閱死者的電腦和手機莹规,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門赔蒲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人良漱,你說我怎么就攤上這事舞虱。” “怎么了母市?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵矾兜,是天一觀的道長。 經(jīng)常有香客問我患久,道長椅寺,這世上最難降的妖魔是什么浑槽? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮返帕,結(jié)果婚禮上桐玻,老公的妹妹穿的比我還像新娘。我一直安慰自己荆萤,他們只是感情好镊靴,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著链韭,像睡著了一般偏竟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上敞峭,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天踊谋,我揣著相機與錄音,去河邊找鬼旋讹。 笑死褪子,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的骗村。 我是一名探鬼主播嫌褪,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼胚股!你這毒婦竟也來了笼痛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤琅拌,失蹤者是張志新(化名)和其女友劉穎缨伊,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體进宝,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡刻坊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了党晋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谭胚。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖未玻,靈堂內(nèi)的尸體忽然破棺而出灾而,到底是詐尸還是另有隱情,我是刑警寧澤扳剿,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布旁趟,位于F島的核電站,受9級特大地震影響庇绽,放射性物質(zhì)發(fā)生泄漏锡搜。R本人自食惡果不足惜橙困,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耕餐。 院中可真熱鬧凡傅,春花似錦、人聲如沸蛾方。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桩砰。三九已至,卻和暖如春释簿,著一層夾襖步出監(jiān)牢的瞬間亚隅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工庶溶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留煮纵,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓偏螺,卻偏偏與公主長得像行疏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子套像,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 程序調(diào)試的基本思想是“分析現(xiàn)象->假設(shè)錯誤原因->產(chǎn)生新的現(xiàn)象去驗證假設(shè)”這樣一個循環(huán)過程酿联,根據(jù)現(xiàn)象如何假設(shè)錯誤原...
    Manfred_Zone閱讀 16,500評論 0 26
  • 概述 GDB是一個由GNU開源組織發(fā)布的、UNIX/Linux操作系統(tǒng)下的夺巩、基于命令行的贞让、功能強大的程序調(diào)試工具。...
    咕咕鷄閱讀 20,714評論 0 8
  • 又來到了一個老生常談的問題柳譬,應(yīng)用層軟件開發(fā)的程序員要不要了解和深入學(xué)習(xí)操作系統(tǒng)呢喳张? 今天就這個問題開始,來談?wù)劜?..
    tangsl閱讀 4,088評論 0 23
  • 從人蒙昧的時候就有了相悅吧?那部記錄了關(guān)關(guān)雎鳩的《詩經(jīng)》說“死生契闊美澳,與子相悅销部;執(zhí)子之手,與子偕老”制跟,時間包容了生...
    青馬文悅閱讀 340評論 0 1
  • 01 我們的知識焦慮凫岖,本質(zhì)上都是財務(wù)狀況焦慮 昨天下午江咳,付費參與了一個小規(guī)模兩小時線下分享活動「绶牛活動亮點不多歼指,我倒...
    富蘭克劉閱讀 690評論 9 20