https://blog.0x972.info/?d=2014/11/13/10/40/50-how-does-a-debugger-work
If I have eight hours for cutting wood, I spend six sharpening my axe.
Showing posts with label Linux. Show all posts
Showing posts with label Linux. Show all posts
Saturday, February 27, 2021
Thursday, November 5, 2020
Kernel Threads
- kthreadd (pid = 2) created by kernel (pid = 0) during boot
- kthreadd helps in creating other kernel threads which are required to run periodically/asynchronously
- "ps" shows kernel threads
- Everything under [square bracket] are kernel threads
sw0:FID128:root> ps -eaf
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 01:21 ? 00:00:00 init [5]
root 2 0 0 01:21 ? 00:00:00 [kthreadd]
root 3 2 0 01:21 ? 00:00:00 [ksoftirqd/0]
root 4 2 0 01:21 ? 00:00:00 [kworker/0:0]
- All calls from user-space to create a new process (including "create_thread" in kthreadd), will end up in do_fork call which internally calls copy_process
Thursday, August 27, 2020
High Mem vs Low Mem
https://linux-kernel-labs.github.io/refs/heads/master/labs/memory_mapping.html
kmalloc: uses low-memory
vmalloc: uses high-memory
Sunday, October 6, 2019
How to Print in Makefile
Source: https://stackoverflow.com/questions/11775733/how-can-i-print-message-in-makefile/11776179
15 # for TRACEGEN
16 include $(MAKEDIR)/Tools.make
17
18 ifeq ($(CONFIG_SOMETHING),y)
19 EXTRA_CFLAGS += -fsanitize=kernel-address
20 $(info ************ TEST VERSION ************)
21 else
22 $(info ************ ELSE VERSION ************)
23 endif
$(info your_text) : Information. This doesn't stop the execution.$(warning your_text) : Warning. This shows the text as a warning.$(error your_text) : Fatal Error. This will stop the execution.
To print a variable in Makefile:
18 $(info $$CONFIG_VAR1 is [${CONFIG_VAR1}])
19 $(info $$CONFIG_VAR2 is [${CONFIG_VAR2}])
Thursday, August 20, 2015
Grep with function name (with different colors) recursively
#!/bin/csh
#
# Maximum can be any parameters (if user has given '*' as files)
#
if ( $#argv < 1 ) then
echo "\n[USAGE]: $0 <pattern> <files>\n";
exit
endif
#awk -v re=$1 '/^[[:alpha:]]/{f=FNR"-"$0} $0~re{printf "%s\n%d:%s\n--\n",f,FNR,$0; f="" }' $2
#awk -v re='CANMIC_MX_LOCK' '/^[[:alpha:]]/{f=FNR"-"$0} $0~re{printf "\033[1;31m%s\n\033[34m%d:\033[0m%s\n--\n",f,FNR,$0; f="" "\033[0m" }' *
#awk -v re=$1 '/^[[:alpha:]]/{f=FNR"-"$0} $0~re{printf "\033[1;31m%s\n\033[34m%d:\033[0m%s\n--\n",f,FNR,$0; f="" "\033[0m" }' $2
foreach i (`find . -name "*" -type f -print`)
awk -v re=$1 '/^[[:alpha:]]/{f=FNR"-"$0} $0~re{printf "\033[1;32m[%15s]\t\033[1;31m%-64s\t\033[34m%s\n--\033[0m\n",FILENAME,f,$0; f="" }' $i
end
#
# Maximum can be any parameters (if user has given '*' as files)
#
if ( $#argv < 1 ) then
echo "\n[USAGE]: $0 <pattern> <files>\n";
exit
endif
#awk -v re=$1 '/^[[:alpha:]]/{f=FNR"-"$0} $0~re{printf "%s\n%d:%s\n--\n",f,FNR,$0; f="" }' $2
#awk -v re='CANMIC_MX_LOCK' '/^[[:alpha:]]/{f=FNR"-"$0} $0~re{printf "\033[1;31m%s\n\033[34m%d:\033[0m%s\n--\n",f,FNR,$0; f="" "\033[0m" }' *
#awk -v re=$1 '/^[[:alpha:]]/{f=FNR"-"$0} $0~re{printf "\033[1;31m%s\n\033[34m%d:\033[0m%s\n--\n",f,FNR,$0; f="" "\033[0m" }' $2
foreach i (`find . -name "*" -type f -print`)
awk -v re=$1 '/^[[:alpha:]]/{f=FNR"-"$0} $0~re{printf "\033[1;32m[%15s]\t\033[1;31m%-64s\t\033[34m%s\n--\033[0m\n",FILENAME,f,$0; f="" }' $i
end
Output:
[./canmic/canmic_err.c] 53-canmic_state_set(int newstate, int *oldstate) CANMIC_MX_LOCK();
--
[./canmic/canmic_err.c] 77-canmic_stateful_write(char *blkdata, size_t blksize, int blknmbr) CANMIC_MX_LOCK();
--
[./canmic/canmic_err.c] 93-canmic_stateful_dirty(scnMsg_t *scnmsg) CANMIC_MX_LOCK();
--
[./canmic/canmic_err1.h] #define CANMIC_MX_LOCK() do { \
--
[./canmic/canmic_err.h] #define CANMIC_MX_LOCK() do { \
[./canmic/canmic_err.c] 53-canmic_state_set(int newstate, int *oldstate) CANMIC_MX_LOCK();
--
[./canmic/canmic_err.c] 77-canmic_stateful_write(char *blkdata, size_t blksize, int blknmbr) CANMIC_MX_LOCK();
--
[./canmic/canmic_err.c] 93-canmic_stateful_dirty(scnMsg_t *scnmsg) CANMIC_MX_LOCK();
--
[./canmic/canmic_err1.h] #define CANMIC_MX_LOCK() do { \
--
[./canmic/canmic_err.h] #define CANMIC_MX_LOCK() do { \
Friday, December 7, 2012
Multithreading - Part 2: Synchronization
Consider the program which we mentioned in "Multithreading - Part 1: Basics"
Program:
#include <stdio.h>
#include <pthread.h>
int gvar;
void* t1_fun(void *msg)
{
int i;
for(i = 0; i < 10; i++)
{
gvar++;
/*printf("[%d:%s] : gvar = %d.\n", pthread_self(), (char*) msg, gvar);*/
printf("[%d:%s] : gvar = %d.\n", (long int)syscall(224), (char*) msg, gvar);
}
}
int main()
{
pthread_t t1, t2;
char *msg1 = "thread1";
char *msg2 = "thread2";
int rc1 = pthread_create(&t1, NULL, t1_fun, (void *) msg1);
if( rc1 ) { printf("Error for thread 1.\n"); perror("pthread_create"); }
int rc2 = pthread_create(&t2, NULL, t1_fun, (void *) msg2);
if( rc2 ) { printf("Error for thread 1.\n"); perror("pthread_create"); }
/* If the 2nd arg is NOT NULL, the return value of t1 and t2 will be stored there.
* This pthread_join will suspend the main thread until the t1/t2 completes, terminates or by calling
* pthread_exit.
*/
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Threads execution over.\n");
return 0;
}
NOTE that if there is no load in the system, this program might print the value of "gvar" as 20 as expected (each thread increments gvar 10 times; hence 20).
But, if you increase the load in the system or if you increase the count in the for loop (replace the count 10 with 50), you can see the threads will fight each other to increment the global variable "gvar". At the end of the program, if you see, the "gvar" will not be "100" as expected; but rather less (see below).
[5164:thread1] : gvar = 95.
[5164:thread1] : gvar = 96.
......
[5165:thread2] : gvar = 95.
[5165:thread2] : gvar = 97.
This kind of situation is called "race condition" where two or more threads will race with each other to change the state of a variable without bothering about the other one.
To avoid this, we have to use mutex.
Mutex (ONLY BETWEEN THREADS IN A SINGLE PROCESS; NOT ACROSS PROCESSES LIKE SEMAPHORE):
Mutexes are used to prevent data inconsistencies due to operations by multiple threads upon the same memory area performed at the same time or to prevent race conditions where an order of operation upon the memory is expected. A contention or race condition often occurs when two or more threads need to perform operations on the same memory area, but the results of computations depends on the order in which these operations are performed. Mutexes are used for serializing shared resources such as memory. Anytime a global resource is accessed by more than one thread the resource should have a Mutex associated with it. Once can apply a mutex to protect a segment of memomry ("critical region") from other threads. Mutexes can be applied only to threads in a single process and do not work between processes as do semaphores.
Modified Program with Mutex:
#include <stdio.h>
#include <pthread.h>
/* Note scope of variable and mutex are the same */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* t1_fun(void *msg)
{
int i;
for(i = 0; i < 100; i++)
{
pthread_mutex_lock( &mutex );
gvar++;
/*printf("[%d:%s] : gvar = %d.\n", pthread_self(), (char*) msg, gvar);*/
printf("[%d:%s] : gvar = %d.\n", (long int)syscall(224), (char*) msg, gvar);
pthread_mutex_unlock( &mutex );
}
}
...
...
Program Output:
$> gcc sample.c -lpthread
$> ls
a.out sample.c
$> ./a.out
...
[5164:thread1] : gvar = 99.
[5164:thread1] : gvar = 100.
......
[5165:thread2] : gvar = 199.
[5165:thread2] : gvar = 200.
Now, no matter how much ever you try executing this program, "gvar" at the end of the program will be always 200 (if you specify 100 as loop count in for loop).
NOTE THAT THE SCOPE OF THE VARIABLE AND THE MUTEX VARIABLE IS SAME. MEANS, GLOBAL VARIABLE PROTECTION SHOULD USE GLOBAL MUTEX VARIABLE!!
Now, no matter how much ever you try executing this program, "gvar" at the end of the program will be always 200 (if you specify 100 as loop count in for loop).
NOTE THAT THE SCOPE OF THE VARIABLE AND THE MUTEX VARIABLE IS SAME. MEANS, GLOBAL VARIABLE PROTECTION SHOULD USE GLOBAL MUTEX VARIABLE!!
Multithreading - Part 1: Basics
Threads: Light-weight Processes (LWP); mostly useful if created in user-space.
Program:
#include <stdio.h>
#include <pthread.h>
int gvar;
void* t1_fun(void *msg)
{
int i;
for(i = 0; i < 10; i++)
{
gvar++;
/*printf("[%d:%s] : gvar = %d.\n", pthread_self(), (char*) msg, gvar);*/
printf("[%d:%s] : gvar = %d.\n", (long int)syscall(224), (char*) msg, gvar);
}
}
int main()
{
pthread_t t1, t2;
char *msg1 = "thread1";
char *msg2 = "thread2";
int rc1 = pthread_create(&t1, NULL, t1_fun, (void *) msg1);
if( rc1 ) { printf("Error for thread 1.\n"); perror("pthread_create"); }
int rc2 = pthread_create(&t2, NULL, t1_fun, (void *) msg2);
if( rc2 ) { printf("Error for thread 1.\n"); perror("pthread_create"); }
printf("Threads execution over.\n");
return 0;
}
Points to Note:
1. The function prototype of the thread should be
void * fun( void * args);
2. Single arguments (like above) can be directly passed after casting to "void *"; where as
multiple arguments can be passed in the form of structures.
3. To print the LWP (thread) ID, I am using the method
(long int) syscall (224) ==> This is the system call for "gettid" system call.
And note, pthread_self() returns "pthread_t"; and not the "thread id".
4. And for both the threads, I can give the same function (t1_fun).
5. Format of pthread_create: pthread_create(&t1, <thread_attr>, <function>, <function_args>)
Program Output:
$> gcc sample.c -lpthread
$> ls
a.out sample.c
$> ./a.out
Threads execution over.
[5164:thread1] : gvar = 1.
[5164:thread1] : gvar = 2.
Why such output?:
The reason is, we have "just triggered the threads and did not bother about them after that".
To make sure, we get all the printfs of both the threads, the main thread should "wait" for those two threads to "join" it.
Hence, if you provide "pthread_join" call for both the threads, you main thread will not exit UNTIL both the threads completes its execution.
...
...
/* If the 2nd arg is NOT NULL, the return value of t1 and t2 will be stored there.
* This pthread_join will suspend the main thread until the t1/t2 completes, terminates or by calling
* pthread_exit.
*/
pthread_join(t1, NULL);
pthread_join(t2, NULL);
Why such output?:
The reason is, we have "just triggered the threads and did not bother about them after that".
To make sure, we get all the printfs of both the threads, the main thread should "wait" for those two threads to "join" it.
Hence, if you provide "pthread_join" call for both the threads, you main thread will not exit UNTIL both the threads completes its execution.
...
...
int rc2 = pthread_create(&t2, NULL, t1_fun, (void *) msg2);
if( rc2 ) { printf("Error for thread 1.\n"); perror("pthread_create"); }
/* If the 2nd arg is NOT NULL, the return value of t1 and t2 will be stored there.
* This pthread_join will suspend the main thread until the t1/t2 completes, terminates or by calling
* pthread_exit.
*/
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Threads execution over.\n");
return 0;
}
Program Output:
$> gcc sample.c -lpthread
$> ls
a.out sample.c
$> ./a.out
[5164:thread1] : gvar = 1.
[5164:thread1] : gvar = 2.
[5164:thread1] : gvar = 3.
[5164:thread1] : gvar = 4.
...
...
[5164:thread1] : gvar = 5.
[5164:thread1] : gvar = 6.
...
...
[5165:thread2] : gvar = 19.
[5165:thread2] : gvar = 20.
Tuesday, October 11, 2011
Sample vimrc file
For vimdiff colorschemes:
- Download github & molokai like below
curl -fLo ~/.vim/colors/molokai.vim --create-dirs https://raw.githubusercontent.com/tomasr/molokai/master/colors/molokai.vim curl -fLo ~/.vim/colors/github.vim --create-dirs https://raw.githubusercontent.com/endel/vim-github-colorscheme/master/colors/github.vim
Then add the below in .vimrc file
if &diff
" colorscheme github
colorscheme molokai
endif<or> ":colorscheme github" diff mode
syntax enable
set incsearch
set nocompatible
set showcmd
set hlsearch
set ai
set si
set ts=4 sw=4 smarttab
set nu
"set nowrap
set formatoptions+=r
set softtabstop=4
set smartindent
set autoindent
set showmatch
"set cursorline
source $HOME/.vim/plugin/taglist.vim
source $HOME/.vim/plugin/comments.vim
"highlight DiffAdd term=reverse cterm=bold ctermbg=white ctermfg=black
"highlight DiffChange term=reverse cterm=bold ctermbg=cyan ctermfg=black
"highlight DiffText term=reverse cterm=bold ctermbg=gray ctermfg=black
"highlight DiffDelete term=reverse cterm=bold ctermbg=cyan ctermfg=black
nnoremap <silent> <F1> :TlistToggle<CR>
"map <C-v><C-v> : vs<cr>
"map <C-q> : q<cr>
command CDC lcd %:p:h
hi LineNr ctermfg=darkyellow
"hi Function ctermfg=cyan
hi Function ctermfg=yellow
"hi Type ctermfg=cyan
hi Type ctermfg=lightred
hi String ctermfg=darkgreen
"hi String ctermfg=150
hi Number ctermfg=brown
"hi Operator ctermfg=brown
hi Search ctermbg=yellow
hi Conditional ctermfg=green
hi Comment ctermfg=lightblue
"""
"if &term =~ "xterm\\|rxvt"
" use an orange cursor in insert mode
"let &t_SI = "\<Esc>]12;orange\x7"
" use a red cursor otherwise
"let &t_EI = "\<Esc>]12;red\x7"
"silent !echo -ne "\033]12;red\007"
"" reset cursor when vim exits
"autocmd VimLeave * silent !echo -ne "\033]112\007"
" use \003]12;gray\007 for gnome-terminal and rxvt up to version 9.21
"endif
highlight Cursor ctermfg=yellow ctermbg=black
"highlight iCursor guifg=white guibg=steelblue
"set guicursor=n-v-c:block-Cursor
"set guicursor+=i:ver100-iCursor
"set guicursor+=n-v-c:blinkon0
"set guicursor+=i:blinkwait10
"""
iab log_this #define LOG_THIS(format, ...) { \<CR>if (access("/harish", F_OK) != -1) { \<CR>char buf1[128] = {}; char buf2[256] = {}; \<CR>char tbuf[20] = {}; time_t now = time(0); struct tm *sTm = gmtime(&now); \<CR>strftime(tbuf, sizeof (tbuf), "%Y-%m-%d %H:%M:%S", sTm); \<CR>snprintf(buf1, sizeof (buf1), "[%s %s:%d]" format, tbuf, __func__, __LINE__, ##__VA_ARGS__); \<CR>snprintf(buf2, sizeof (buf2), "echo '%s' >> /harish_log", buf1); \<CR>system(buf2); } }
set incsearch
set nocompatible
set showcmd
set hlsearch
set ai
set si
set ts=4 sw=4 smarttab
set nu
"set nowrap
set formatoptions+=r
set softtabstop=4
set smartindent
set autoindent
set showmatch
"set cursorline
source $HOME/.vim/plugin/taglist.vim
source $HOME/.vim/plugin/comments.vim
"highlight DiffAdd term=reverse cterm=bold ctermbg=white ctermfg=black
"highlight DiffChange term=reverse cterm=bold ctermbg=cyan ctermfg=black
"highlight DiffText term=reverse cterm=bold ctermbg=gray ctermfg=black
"highlight DiffDelete term=reverse cterm=bold ctermbg=cyan ctermfg=black
nnoremap <silent> <F1> :TlistToggle<CR>
"map <C-v><C-v> : vs<cr>
"map <C-q> : q<cr>
command CDC lcd %:p:h
hi LineNr ctermfg=darkyellow
"hi Function ctermfg=cyan
hi Function ctermfg=yellow
"hi Type ctermfg=cyan
hi Type ctermfg=lightred
hi String ctermfg=darkgreen
"hi String ctermfg=150
hi Number ctermfg=brown
"hi Operator ctermfg=brown
hi Search ctermbg=yellow
hi Conditional ctermfg=green
hi Comment ctermfg=lightblue
"""
"if &term =~ "xterm\\|rxvt"
" use an orange cursor in insert mode
"let &t_SI = "\<Esc>]12;orange\x7"
" use a red cursor otherwise
"let &t_EI = "\<Esc>]12;red\x7"
"silent !echo -ne "\033]12;red\007"
"" reset cursor when vim exits
"autocmd VimLeave * silent !echo -ne "\033]112\007"
" use \003]12;gray\007 for gnome-terminal and rxvt up to version 9.21
"endif
highlight Cursor ctermfg=yellow ctermbg=black
"highlight iCursor guifg=white guibg=steelblue
"set guicursor=n-v-c:block-Cursor
"set guicursor+=i:ver100-iCursor
"set guicursor+=n-v-c:blinkon0
"set guicursor+=i:blinkwait10
"""
" Copyright abbreviations
iab cfn /*<CR>Function<CR><CR>Description<CR><CR>Parameter(s)<CR><CR>Return Value<CR>/<Up><Up><Up><Up><Up><Up>
iab todo // TODO Remove this
iab cpr Broadcom Proprietary and Confidential. Copyright © 2019 Broadcom.<CR>All Rights Reserved.<CR>The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
iab testbin TOPDIR<TAB>= ../../..<CR>MAKEDIR<TAB>= $(TOPDIR)/make<CR><CR>include $(MAKEDIR)/Tools.make<CR>include $(MAKEDIR)/Targets.make<CR>include $(MAKEDIR)/Fabos.make<CR>include $(MAKEDIR)/Man.make<CR><CR>TESTBIN = testbin<CR>TESTBIN_SRCS = testbin.c<CR>TESTBIN_OBJS = $(TESTBIN_SRCS:.c=.o)<CR><CR>$(TESTBIN): $(TESTBIN_OBJS)<CR><TAB>$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)<CR>all:: $(TESTBIN)<CR><CR>clean::<CR><TAB>rm $(TESTBIN) $(TESTBIN_OBJS)
iab log_this #define LOG_THIS(format, ...) { \<CR>if (access("/harish", F_OK) != -1) { \<CR>char buf1[128] = {}; char buf2[256] = {}; \<CR>char tbuf[20] = {}; time_t now = time(0); struct tm *sTm = gmtime(&now); \<CR>strftime(tbuf, sizeof (tbuf), "%Y-%m-%d %H:%M:%S", sTm); \<CR>snprintf(buf1, sizeof (buf1), "[%s %s:%d]" format, tbuf, __func__, __LINE__, ##__VA_ARGS__); \<CR>snprintf(buf2, sizeof (buf2), "echo '%s' >> /harish_log", buf1); \<CR>system(buf2); } }
function! LoadCscope()
let db = findfile("cscope.out", ".;")
if (!empty(db))
let path = strpart(db, 0, match(db, "/cscope.out$"))
set nocscopeverbose " suppress 'duplicate connection' error
exe "cs add " . db . " " . path
set cscopeverbose
" else add the database pointed to by environment variable
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
endfunction
"au BufEnter /* call LoadCscope()
" http://cscope.sourceforge.net/cscope_maps.vim
nmap <C-\>ss :cs find s <C-R>=expand("<cword>")<CR><CR>
"nmap <C-\>g :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>cc :cs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>tt :cs find t <C-R>=expand("<cword>")<CR><CR>
"nmap <C-\>e :cs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>ff :cs find f <C-R>=expand("<cfile>")<CR><CR>
"nmap <C-\>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
"nmap <C-\>d :cs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>s :cs find s
nmap <C-\>g :cs find g
nmap <C-\>c :cs find c
nmap <C-\>t :cs find t
nmap <C-\>e :cs find e
nmap <C-\>f :cs find f
nmap <C-\>i :cs find i
nmap <C-\>d :cs find d
" quick fix options
nmap qf :set cscopequickfix=s-,c-,d-,i-,t-,e-
nmap noqf :set cscopequickfix=""
nmap cw :cwindow
nmap <C-\>ss :cs find s <C-R>=expand("<cword>")<CR><CR>
"nmap <C-\>g :cs find g <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>cc :cs find c <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>tt :cs find t <C-R>=expand("<cword>")<CR><CR>
"nmap <C-\>e :cs find e <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>ff :cs find f <C-R>=expand("<cfile>")<CR><CR>
"nmap <C-\>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
"nmap <C-\>d :cs find d <C-R>=expand("<cword>")<CR><CR>
nmap <C-\>s :cs find s
nmap <C-\>g :cs find g
nmap <C-\>c :cs find c
nmap <C-\>t :cs find t
nmap <C-\>e :cs find e
nmap <C-\>f :cs find f
nmap <C-\>i :cs find i
nmap <C-\>d :cs find d
" quick fix options
nmap qf :set cscopequickfix=s-,c-,d-,i-,t-,e-
nmap noqf :set cscopequickfix=""
nmap cw :cwindow
"function! AddCscope()
"echom "Adding CSCOPE file.. please wait"
"silent! exec "r!goto_base_ws"
":cs add cscope.files
"endfunction
"nnoremap <silent> <F3> :call AddCscope()<CR>
"nnoremap <F3> :! ~/bin/goto_base_ws && cd vobs/projects/springboard/fabos <CR>:cs add cscope.files<CR>
Subscribe to:
Posts (Atom)

