#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define LWIP_UNUSED_ARG(x) (void)x
typedef int sys_prot_t;
static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_t lwprot_thread = (pthread_t)0xDEAD;
static int lwprot_count = 0;
sys_prot_t
sys_arch_protect(void)
{
if(lwprot_thread != pthread_self())
{
pthread_mutex_lock(&lwprot_mutex);
lwprot_thread = pthread_self();
lwprot_count = 1;
}
else
{
lwprot_count++;
}
return 0;
}
void
sys_arch_unprotect(sys_prot_t pval)
{
LWIP_UNUSED_ARG(pval);
if(lwprot_thread == pthread_self())
{
if(--lwprot_count == 0)
{
lwprot_thread = (pthread_t)0xDEAD;
pthread_mutex_unlock(&lwprot_mutex);
}
}
}
int g_iGloNum = 0;
void * thread(void * pArg)
{
for (int i = 0; i < 10; i++)
{
sys_arch_protect();
printf("thread g_iGloNum=%d\n", ++g_iGloNum);
sys_arch_unprotect(0);
sleep(1);
}
return NULL;
}
int main()
{
printf("hello world! g_iGloNum=%d\n", g_iGloNum);
pthread_t iThreadID;
pthread_create(&iThreadID, NULL, thread, NULL);
for (int i = 0; i < 10; i++)
{
sys_arch_protect();
printf("main g_iGloNum=%d\n", --g_iGloNum);
sys_arch_unprotect(0);
sleep(2);
}
pthread_join(iThreadID, NULL);
return 0;
}
g++ main.cpp -pthread
QGraphicsDropShadowEffect *wndShadow = new QGraphicsDropShadowEffect;
wndShadow->setBlurRadius(9.0);
wndShadow->setColor(QColor(0, 0, 0, 160));
wndShadow->setOffset(4.0);
ui->localState_toolButton->setGraphicsEffect(wndShadow);
//let the window icon in taskbar when clicked, it can max or min the window
this->setWindowFlags(Qt::Window|Qt::FramelessWindowHint
|Qt::WindowSystemMenuHint|Qt::WindowMinimizeButtonHint|Qt::WindowMaximizeButtonHint);
apt-get source coreutils
获取常用工具的源码,例如 ls 。等学会了用gdb就可以调试常用工具的源码了。
写个简单的程序用来调试。
//main.c
#include <stdio.h>
int func(int n)
{
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += i;
}
return sum;
}
int main()
{
int iResult = 0;
for (int i = 0; i <= 100; i++)
{
iResult += i;
}
printf("result[1-100] = %d\n", iResult);
printf("result[1-250] = %d\n", func(250));
return 0;
}
编译命令
g++ -g main.c -o test
要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。要加上 -g 的選項. (可以用-g, -g2, -g3具體請看 man gcc)通常如果程式不會很大,在 compile 的時候我都是用 -g3 的,因為如果你用到了 inline 的 function, 用 -g 去 compile 就無法去 debug inline function了.這時候就用到 -g2, -g3了,g後面的數字越大,也就是說 可以 debug 的級別越高.最高級別就是 -g3.
root@mdgsf-VirtualBox:# gdb test <-------------------------开始调试
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 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".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...done.
(gdb) l <--------------------- l命令相当于list,列出原码,不知道为什么不是从第一行开始。
6 for (int i = 0; i < n; i++)
7 {
8 sum += i;
9 }
10 return sum;
11 }
12
13 int main()
14 {
15 int iResult = 0;
(gdb) list <--------------------- list,列出原码。
16 for (int i = 0; i <= 100; i++)
17 {
18 iResult += i;
19 }
20 printf("result[1-100] = %d\n", iResult);
21 printf("result[1-250] = %d\n", func(250));
22 return 0;
23 }
(gdb) list <--------------------- list,列出原码。
Line number 24 out of range; main.c has 23 lines.
(gdb) l 0 <--------------------- 用list命令从第一行开始列出代码。
1 #include <stdio.h>
2
3 int func(int n)
4 {
5 int sum = 0;
6 for (int i = 0; i < n; i++)
7 {
8 sum += i;
9 }
10 return sum;
(gdb) <--------------------- 直接回车,重复执行上一个命令。
11 }
12
13 int main()
14 {
15 int iResult = 0;
16 for (int i = 0; i <= 100; i++)
17 {
18 iResult += i;
19 }
20 printf("result[1-100] = %d\n", iResult);
(gdb) break 15 <--------------------- 在程序的第15行设置断点
Breakpoint 1 at 0x8048453: file main.c, line 15.
(gdb) break func <--------------------- 在程序的func()函数入口设置断点
Breakpoint 2 at 0x8048423: file main.c, line 5.
(gdb) info break <--------------------- 查看断点的信息
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048453 in main() at main.c:15
2 breakpoint keep y 0x08048423 in func(int) at main.c:5
(gdb) r <--------------------- r (run) 运行程序
Starting program: /root/gdb/test
Breakpoint 1, main () at main.c:15
15 int iResult = 0;
(gdb) n <--------------------- 单条语句执行,next命令简写。
16 for (int i = 0; i <= 100; i++)
(gdb) n <--------------------- 单条语句执行,next命令简写。
18 iResult += i;
(gdb) c <--------------------- c (continue) 继续运行程序。
Continuing.
result[1-100] = 5050 <----------程序输出。
Breakpoint 2, func (n=250) at main.c:5
5 int sum = 0;
(gdb) info break <--------------------- 查看断点的信息
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048453 in main() at main.c:15
breakpoint already hit 1 time
2 breakpoint keep y 0x08048423 in func(int) at main.c:5
breakpoint already hit 1 time
(gdb) n
6 for (int i = 0; i < n; i++)
(gdb) n
8 sum += i;
(gdb) p i <--------------------- 打印变量i的值,print命令简写。
$1 = 1
(gdb) p sum <--------------------- 打印变量sum的值,print命令简写。
$2 = 0
(gdb) p i
$3 = 1
(gdb) n
6 for (int i = 0; i < n; i++)
(gdb) n
8 sum += i;
(gdb) n
6 for (int i = 0; i < n; i++)
(gdb) p i
$4 = 2
(gdb) p sum
$5 = 3
(gdb) bt <--------------------- 查看函数堆栈。
#0 func (n=250) at main.c:6
#1 0x08048499 in main () at main.c:21
(gdb) finish <--------------------- 退出函数。
Run till exit from #0 func (n=250) at main.c:6
0x08048499 in main () at main.c:21
21 printf("result[1-250] = %d\n", func(250));
Value returned is $6 = 31125
(gdb) c <--------------------- 继续运行。
Continuing.
result[1-250] = 31125 <----------程序输出。
[Inferior 1 (process 10367) exited normally] <--------程序退出,调试结束。
(gdb) q <--------------------- 退出gdb
常用命令简写:
list --> l 列出源代码
run --> r 运行程序
next --> n
continue --> c
print --> p
backtrace --> bt
(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.
gdb的命令很多,gdb把之分成许多个种类。help命令只是例出gdb的命令种类,如果要看种类中的命令,可以使用help
(gdb) help list <-----------------------用 help 命令查看具体用法
List specified function or line.
With no argument, lists ten more lines after or around previous listing.
"list -" lists the ten lines before a previous ten-line listing.
One argument specifies a line, and ten lines are listed around that line.
Two arguments with comma between specify starting and ending lines to list.
Lines can be specified in these ways:
LINENUM, to list around that line in current file,
FILE:LINENUM, to list around that line in that file,
FUNCTION, to list around beginning of that function,
FILE:FUNCTION, to distinguish among like-named static functions.
*ADDRESS, to list around the line containing that address.
With two args if one is empty it stands for ten lines away from the other arg.
(gdb) help break
Set breakpoint at specified line or function.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point. Accepted values are `-probe' (for a generic, automatically
guessed probe type) or `-probe-stap' (for a SystemTap probe).
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of the selected
stack frame. This is useful for breaking on return to a stack frame.
THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
Multiple breakpoints at one place are permitted, and useful if their
conditions are different.
Do "help breakpoints" for info on other commands dealing with breakpoints.
(gdb) help run
Start debugged program. You may specify arguments to give it.
Args may include "*", or "[...]"; they are expanded using "sh".
Input and output redirection with ">", "<", or ">>" are also allowed.
With no arguments, uses arguments last specified (with "run" or "set args").
To cancel previous arguments and run with no arguments,
use "set args" without arguments.
(gdb) help next
Step program, proceeding through subroutine calls.
Usage: next [N]
Unlike "step", if the current source line calls a subroutine,
this command does not enter the subroutine, but instead steps over
the call, in effect treating it as a single source line.
(gdb) help continue
Continue program being debugged, after signal or breakpoint.
Usage: continue [N]
If proceeding from breakpoint, a number N may be used as an argument,
which means to set the ignore count of that breakpoint to N - 1 (so that
the breakpoint won't break until the Nth time it is reached).
If non-stop mode is enabled, continue only the current thread,
otherwise all the threads in the program are continued. To
continue all stopped threads in non-stop mode, use the -a option.
Specifying -a and an ignore count simultaneously is an error.
(gdb) help print
Print value of expression EXP.
Variables accessible are those of the lexical environment of the selected
stack frame, plus all those whose scope is global or an entire file.
$NUM gets previous value number NUM. $ and $$ are the last two values.
$$NUM refers to NUM'th value back from the last one.
Names starting with $ refer to registers (with the values they would have
if the program were to return to the stack frame now selected, restoring
all registers saved by frames farther in) or else to debugger
"convenience" variables (any such name not a known register).
Use assignment expressions to give values to convenience variables.
{TYPE}ADREXP refers to a datum of data type TYPE, located at address ADREXP.
@ is a binary operator for treating consecutive data objects
anywhere in memory as an array. FOO@NUM gives an array whose first
element is FOO, whose second element is stored in the space following
where FOO is stored, etc. FOO must be an expression whose value
resides in memory.
EXP may be preceded with /FMT, where FMT is a format letter
but no count or size letter (see "x" command).
(gdb) help bt
Print backtrace of all stack frames, or innermost COUNT frames.
With a negative argument, print outermost -COUNT frames.
Use of the 'full' qualifier also prints the values of the local variables.
Use of the 'no-filters' qualifier prohibits frame filters from executing
on this backtrace.
#define GLOG_NO_ABBREVIATED_SEVERITIES
/*
* INFO = GLOG_INFO,
* WARNING = GLOG_WARNING,
* ERROR = GLOG_ERROR,
* FATAL = GLOG_FATAL;
*/
#include <iostream>
#include <stdio.h>
#include <glog/logging.h>
using namespace std;
void vTestLog();
int main(int argc, char * argv[])
{
printf("glog demo\n");
// GLog生成的文件名格式是[文件名].[计算机名].[Windows用户名].[log].[等级].[年月日时分秒].[PID]
// Initialize Google's logging library,同时设置文件名
google::InitGoogleLogging(argv[0]);
google::LogToStderr();//只输出到标准错误输出,也就是不保存到文件中。
google::SetStderrLogging(google::GLOG_INFO); //设置级别高于 google::INFO 的日志同时输出到屏幕
FLAGS_log_dir = "c:\\GLogFiles"; //设置保存log的目录
FLAGS_colorlogtostderr = true; //设置输出到屏幕的日志显示相应颜色
FLAGS_logbufsecs = 0; //缓冲日志输出,默认为30秒,此处改为立即输出
FLAGS_max_log_size = 100; //最大日志大小为 100MB
FLAGS_stop_logging_if_full_disk = true; //当磁盘被写满时,停止日志输出
vTestLog();
google::ShutdownGoogleLogging();
getchar();getchar();
return 0;
}
void vTestLog()
{
LOG(INFO) << "google INFO log" << endl;
LOG(WARNING) << "google WARNING log" << endl;
LOG(ERROR) << "google ERROR log" << endl; //ERROR级别的log默认会同时输出到console和文件
//LOG(FATAL) << "google FATAL log" << endl; //FATAL级别的log一旦执行到了,程序就会自动推出
int i;
for (i = 0; i < 10; i++) {
//当条件满足时输出日志
LOG_IF(INFO, i>7) << "i = " << i;
}
for (i = 0; i < 10; i++) {
//google::COUNTER 记录该语句被执行次数,
//从1开始,在第一次运行输出日志之后,每隔 3 次再输出一次日志信息
LOG_EVERY_N(INFO, 3) << "Got the" << google::COUNTER << "th i=" << i;
}
for (i = 0; i < 10; i++) {
//当此语句执行的前 3 次都输出日志,然后不再输出
LOG_FIRST_N(INFO, 3) << "FIRST Got the" << google::COUNTER << "th i=" << i;
}
//LOG(ERROR) << "LOG";
//VLOG(3) << "VLOG";
//DLOG(ERROR) << "DLOG";
//DVLOG(3) << "DVLOG";
//SYSLOG(ERROR) <<"SYSLOG";
//PLOG(ERROR) <<"PLOG";
//RAW_LOG(ERROR, "RAW_LOG");
}
Vundle 是一个vim插件,它可以管理其它的vim插件,比如说帮你下载安装。
https://github.com/VundleVim/Vundle.vim
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
然后在 ~/.vimrc 中添加
" vundle Brief help
" :PluginList -lists configured plugins
" :PluginInstall - installs plugins; append '!' to update or just :PluginUpdate
" :PluginSearch foo - search for foo; append '!' to refresh local cache
" :PluginClean - confirms removal of unused plugins; append '!' to auto-approve removal
set nocompatible
filetype off
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
call vundle#end()
filetype plugin indent on
然后打开vim,执行 :PluginInstall 等待它自动从网上下载安装就可以了。
在最下面的状态栏可以看到当前处理的状态。
autoformat 是一个vim插件,能够自动格式化c,c++文件。
https://github.com/Chiel92/vim-autoformat#default-formatprograms
因为上面我们已经安装了 vundle ,所以我们现在可以通过 vundle 来安装 auto-format 。
在 ~/.vimrc 中添加
Plugin 'Chiel92/vim-autoformat'
然后打开vim,执行 :PluginInstall 等待它自动从网上下载安装就可以了。
就是这么简单。
需要注意的是,vim-autoformat只是格式化程序框架,它依赖于代码风格检查工具来进行格式化。
我们需要单独安装这些工具:astyle
svn checkout "https://svn.code.sf.net/p/astyle/code/trunk/AStyle"
cd AStyle/build/gcc
make
make install
然后 astyle 会默认安装在 /usr/bin 目录下。具体见(AStyle/doc/astyle.html)
astyle 常用的参数:
--style=ansi
--add-brackets(-j) : Add brackets to unbracketed one line conditional statements (e.g. 'if', 'for', 'while'...). The statement must be on a single line.
--pad-oper(-p) : Insert space padding around operators.
--align-reference=middle(-W2)
--align-pointer=middle(-k2)
--indent-namespaces(-N) : Add extra indentation to namespace blocks.
--indent-preproc-define(-w)
--indent-preproc-block(-xW) :
--indent-switches
--indent-cases(-K)
完整的 ~/.vimrc
" vundle Brief help
" :PluginList -lists configured plugins
" :PluginInstall - installs plugins; append '!' to update or just :PluginUpdate
" :PluginSearch foo - search for foo; append '!' to refresh local cache
" :PluginClean - confirms removal of unused plugins; append '!' to auto-approve removal
set nocompatible
filetype off
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'fatih/vim-go'
Plugin 'Chiel92/vim-autoformat'
Plugin 'scrooloose/nerdtree'
call vundle#end()
filetype plugin indent on
" vim-autoformat
"""""""""""""""""""""""""""""""""""""""""
let g:formatterpath = ['/usr/bin', '']
noremap <F3> :Autoformat<CR>
"au BufWrite * :Autoformat "when you save file, it will auto format your file.
let g:autoformat_autoindent = 0
let g:autoformat_retab = 0
let g:autoformat_remove_trailing_spaces = 0
" --style=ansi --add-brackets(-j) --pad-oper(-p)
" --align-reference=middle(-W2) --align-pointer=middle(-k2)
" --indent-namespaces(-N) --indent-preproc-define(-w)
" --indent-switches --indent-cases(-K) --indent-preproc-block(-xW)
let g:formatdef_jian = '"astyle --style=ansi -j -p -W2 -k2 -N -w -K -xW"'
let g:formatters_cpp = ['jian']
let g:formatters_java = ['jian']
let g:formatters_c = ['jian']
" autocmd FileType vim,tex let b:autoformat_autoindent=0
" gg=G
" :retab
" :RemoveTrailingSpaces
"common
""""""""""""""""""""""""""""""""""""""""""
if has("syntax")
syntax enable
syntax on
endif
if has('mouse')
set mouse=a " Enable mouse usage (all modes)
endif
filetype plugin on
filetype indent on
set autoread "set to auto read when a file is changed from the outside.
set ambiwidth=double "for some unicode special character.
set whichwrap=b,s,<,>,[,]
set nocompatible "close vi compatible mode
set backspace=indent,eol,start
set history=100
set cursorline "current line will have a underline.
set hlsearch " hight light search
set number
set ruler "display cursor position in the right corner of the vim window
set magic "set magic on, for regular expression
set noautochdir
set nocompatible " Use Vim defaults
set ignorecase " ignore case
set incsearch " display when you still typing
set wrapscan " stop the scan at the end of file
set wrap
set hidden
set vb t_vb= "close the voice when cmd error.
" Show autocomplete menus.
set wildmenu
" Minimal number of screen lines to keep above and below the cursor.
"set scrolloff=999
"indent
""""""""""""""""""""""""""""""""""""""""""
"set expandtab "tab will auto changed to blank space, (Ctrl+V+tab will input real tab), Makefile command need tab.
set smartindent " (set si)
set smarttab
set tabstop=4 " tab stop (set ts=4)
set shiftwidth=4 " shift width
set softtabstop=4
set autoindent " auto indent (set ai)
set wrap "Wrap lines
map <F5> :set ts=4<CR>:set expandtab<CR>:%retab!<CR>
map <C-F5> :set ts=4<CR>:set noexpandtab<CR>:%retab!<CR>
" NERD tree
""""""""""""""""""""""""""""""""""""""""""""
map <F10> :NERDTreeToggle<CR>
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
"fold
""""""""""""""""""""""""""""""""""""""""""
set foldenable
set foldmethod=syntax "index, expr, marker, syntax, diff
"set foldclose=all
" use space to folden, zo:open the fold, zc:fold.
nnoremap <space> @=((foldclosed(line( '.' ))<0) ? 'zc' : 'zo')<CR>
set foldopen-=search "don't open folds when I search
set foldopen-=undo "don't open folds when I undo
set foldlevel=100 "don't folds when I open the file
"set foldcolumn=1 "set the fold column width
"Linebreak on 500 characters
""""""""""""""""""""""""""""""""""""""""""
set tw=500
set lbr
set fo+=mB "support for chinese.
"set mapleader
let mapleader="," "mapleader default is '/', <leader> is mapleader.
let g:mapleader=","
"use ,s to source .vimrc
map <silent> <leader>s :source ~/.vimrc<CR>
"use ,e to open .vimrc
map <silent> <leader>e :e ~/.vimrc<CR>
"auto source .vimrc after edit .vimrc
autocmd! bufwritepost .vimrc source ~/.vimrc
au BufNewFile,BufRead *.cpp,*.c,*.h set syntax=cpp11
"use , to remove highlight search
nmap <silent> <leader><CR> :noh<CR>
nmap <leader>w :w!<cr>
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
map <leader>v :vsplit<CR>
map <C-A> ggvGY
map! <C-A> <Esc>ggvGY
map <F2> <Esc>:tabnew<CR>
map <C-P> :tabprev<CR>
map <C-N> :tabnext<CR>
map <C-C> :tabclose<CR>
"nnoremap <F3> :g/^\s*$/d<CR> "this will delete all blank line in file.
"map <C-H> :hide<CR>
"map <C-J> :tn<CR>
"map <C-K> :tp<CR>
"map <C-L> :cd .<CR>
map \p i(<Esc>ea)<Esc>
map \c i{<Esc>ea}<Esc>
map \n :nohlsearch<CR>