但 Linux 系統預設的 fd_set size 只有 1024,若同時間處理的 fd 超過 1024 就會出問題
修改下面這兩個檔案,重新 build application 時就會引用到新的 define 值
/usr/include/bits/typesizes.h:
#define __FD_SETSIZE 1024
/usr/include/linux/posix_types.h:
#define __FD_SETSIZE 1024
#define __FD_SETSIZE 1024
#define __FD_SETSIZE 1024
Dnsmasq is a lightweight, easy to configure DNS forwarder and DHCP server.酷!一次滿足兩個願望
$ yum install dnsmasq
$ vim /etc/dnsmasq.resolv.conf nameserver 8.8.8.8
$ vim /etc/hosts 10.0.0.1 anything.com.tw
$ /etc/init.d/dnsmasq start
$ gcc -g -o hello hello.c
$ gdb ./hello
$ gdb -d /home/brian/test ./hello
$ gdb ./hello 12238
(GDB) run若要帶參數的話
run (init parameter) Ex: (GDB) run -h localhost -p 8080
b (filename):(line num) Ex: (GDB) b hello.c:5
(GDB) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x000000000040049c in main at hello.c:5
d (breakpoint id) Ex: (GDB) d 1
(GDB) bt #0 hello () at hello.c:9 #1 0x00000000004004cf in main () at hello.c:14
(GDB) bt full
#0 hello () at hello.c:9
i = 0
#1 0x00000000004004cf in main () at hello.c:14
No locals.
p (variable) Ex: (GDB) p iValue (GDB) p *stEmployee
f (frame num) EX: (GDB) f 3
(GDB) nStep into (會跳入 function)
(GDB) sContinue
(GDB) c
(GDB) handle SIGUSR nostop noprint
(GDB) i handle Signal Stop Print Pass to program Description SIGHUP Yes Yes Yes Hangup SIGINT Yes Yes No Interrupt SIGQUIT Yes Yes Yes Quit SIGILL Yes Yes Yes Illegal instruction SIGTRAP Yes Yes No Trace/breakpoint trap有關 signal 的部分可以參考 http://sourceware.org/gdb
(GDB) thread
(GDB) thread 3
(GDB) thread apply all bt (GDB) thread apply all bt full
sudo: /etc/sudoers is mode 0640, should be 0440
sudo: no valid sudoers sources found, quitting
$ opcontrol --init $ opcontrol --reset $ opcontrol --setup --no-vmlinux --separate=library $ opcontrol --start--separate=none: 只想看程式本身的 function
$ ./app
$ opcontrol --dump $ opcontrol --stop $ opcontrol -h
$ opreport -l ./app CPU: CPU with timer interrupt, speed 1999.97 MHz (estimated) Profiling through timer interrupt samples % image name symbol name 7251 30.3186 libx264.so.128 x264_cavlc_init 6247 26.1206 libx264.so.128 x264_coeff_level_run16 3018 12.6192 libx264.so.128 x264_analyse_init_costs encoder/analyse.c:292 1496 6.2552 libavcodec.so.52.72.2 /opt/ffmpeg-0.6.5/lib/libavcodec.so.52.72.2 1426 5.9625 libc-2.12.so __strcmp_sse42 1120 4.6831 libm-2.12.so __ieee754_log2f 384 1.6056 libavformat.so.52.64.2 /opt/ffmpeg-0.6.5/lib/libavformat.so.52.64.2 329 1.3756 libc-2.12.so memcpy 239 0.9993 libc-2.12.so _int_malloc 213 0.8906 libm-2.12.so __ieee754_pow 180 0.7526 libx264.so.128 x264_cqm_init
$ opannotate --source ./app
... (執行次數) (花費比例)
:static uint64_t pop_buffer_value(struct transient * trans)
11510 1.9661 :{ /* pop_buffer_value total: 89901 15.3566 */
: uint64_t val;
:
10227 1.7469 : if (!trans->remaining) {
: fprintf(stderr, "BUG: popping empty buffer !\n");
: exit(EXIT_FAILURE);
: }
:
: val = get_buffer_value(trans->buffer, 0);
2281 0.3896 : trans->remaining--;
2296 0.3922 : trans->buffer += kernel_pointer_size;
: return val;
10454 1.7857 :}
...
opcontrol --deinit modprobe oprofile timer=1 opcontrol --reset opcontrol --no-vmlinux --separate=library opcontrol --start
#include#include #include #include #include #include #include #include #define LOCAL_IP "127.0.0.1" #define LOCAL_PORT 5678 #define SVR_IP "127.0.0.1" #define SVR_PORT 8080 #define BUF_SIZE 1024 #define MESSAGE "hello" int main (int argc, char **argv) { struct sockaddr_in local_addr, server_addr; socklen_t len; int sock_fd; char buff[BUF_SIZE]; int recv_len; len = sizeof(struct sockaddr_in); /* Set local address (In general, we don't care local address) */ memset(&local_addr, 0, sizeof(local_addr)); local_addr.sin_family = AF_INET; local_addr.sin_addr.s_addr = inet_addr(LOCAL_IP); local_addr.sin_port = htons(LOCAL_PORT); /* Set server address */ memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(SVR_IP); server_addr.sin_port = htons(SVR_PORT); /* Create endpoint */ if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket()"); return -1; } else { printf("sock_fd=[%d]\n", sock_fd); } /* Bind */ if (bind(sock_fd, (struct sockaddr *)&local_addr, sizeof(local_addr)) == -1) { perror("bind()"); return -1; } else { printf("bind [%s:%u] success\n", inet_ntoa(local_addr.sin_addr), ntohs(local_addr.sin_port)); } /* Connect */ if (connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("connect()"); return -1; } else { printf("connect to [%s:%u] success\n", inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); } /* Send */ send(sock_fd, MESSAGE, strlen(MESSAGE), 0); /* Receive */ memset(buff, 0, sizeof(buff)); recv_len = recv(sock_fd, buff, sizeof(buff), 0); if (recv_len == -1) { perror("recv()"); return -1; } else if (recv_len == 0) { printf("Client disconnect\n"); } else { printf("Receive: len=[%d] msg=[%s]\n", recv_len, buff); } return 0; }
#include#include #include #include #include #include #include #include #define SVR_IP "127.0.0.1" #define SVR_PORT 8080 #define BUF_SIZE 1024 int main (int argc, char **argv) { struct sockaddr_in server_addr; socklen_t len; fd_set active_fd_set; int sock_fd; int max_fd; int flag = 1; char buff[BUF_SIZE]; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(SVR_IP); server_addr.sin_port = htons(SVR_PORT); len = sizeof(struct sockaddr_in); /* Create endpoint */ if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket()"); return -1; } else { printf("sock_fd=[%d]\n", sock_fd); } /* Set socket option */ if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int)) < 0) { perror("setsockopt()"); return -1; } /* Bind */ if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("bind()"); return -1; } else { printf("bind [%s:%u] success\n", inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port)); } /* Listen */ if (listen(sock_fd, 128) == -1) { perror("listen()"); return -1; } FD_ZERO(&active_fd_set); FD_SET(sock_fd, &active_fd_set); max_fd = sock_fd; while (1) { int ret; struct timeval tv; fd_set read_fds; /* Set timeout */ tv.tv_sec = 2; tv.tv_usec = 0; /* Copy fd set */ read_fds = active_fd_set; ret = select(max_fd + 1, &read_fds, NULL, NULL, &tv); if (ret == -1) { perror("select()"); return -1; } else if (ret == 0) { printf("select timeout\n"); continue; } else { int i; /* Service all sockets */ for (i = 0; i < FD_SETSIZE; i++) { if (FD_ISSET(i, &read_fds)) { if (i == sock_fd) { /* Connection request on original socket. */ struct sockaddr_in client_addr; int new_fd; /* Accept */ new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &len); if (new_fd == -1) { perror("accept()"); return -1; } else { printf("Accpet client come from [%s:%u] by fd [%d]\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), new_fd); /* Add to fd set */ FD_SET(new_fd, &active_fd_set); if (new_fd > max_fd) max_fd = new_fd; } } else { /* Data arriving on an already-connected socket */ int recv_len; /* Receive */ memset(buff, 0, sizeof(buff)); recv_len = recv(i, buff, sizeof(buff), 0); if (recv_len == -1) { perror("recv()"); return -1; } else if (recv_len == 0) { printf("Client disconnect\n"); } else { printf("Receive: len=[%d] msg=[%s]\n", recv_len, buff); /* Send (In fact we should determine when it can be written)*/ send(i, buff, recv_len, 0); } /* Clean up */ close(i); FD_CLR(i, &active_fd_set); } } // end of if } //end of for } // end of if } // end of while return 0; }
(sock_fd is a socket)
sockaddr_in addr_in;
int len = sizeof(sockaddr_in);
/* Get sockaddr_in structure information from socket */
getsockname(sock_fd, (sockaddr *)&addr_in, (socklen_t *)&len);
/* Get address from sockaddr_in */
printf("IP=[%s] port=[%d]\n", inet_ntoa(addr_in.sin_addr), addr_in.sin_port);
#include#include int main(void) { char *p; mtrace(); p = malloc(5); // 要一塊記憶體,但沒有釋放 return 0; }
$ gcc -g -o test test.c一定要加-g
$ MALLOC_TRACE=output.log ./testMALLOC_TRACE指向output file
$ mtrace ./test ./output.log結果:
Memory not freed:
-----------------
Address Size Caller
0x0000000000c2d460 0x5 at /tmp/test.c:8
很清楚看到test.c第8行allocate 5 byte未釋放#include#include #include int main(void) { GHashTable *ht; mtrace(); ht = g_hash_table_new(NULL, NULL); return 0; }
Memory not freed:
-----------------
Address Size Caller
0x0000000012a24460 0xfc at 0x2b267c24f3b1
0x0000000012a24570 0x1f8 at 0x2b267c24f3b1
0x0000000012a24770 0x1f8 at 0x2b267c24f3b1
0x0000000012a24970 0x7f0 at 0x2b267c24f3b1
0x0000000012a25170 0xc0 at 0x2b267c24f3b1
0x0000000012a25400 0x3f0 at 0x2b267c262ce1
0x0000000012a25800 0x3f0 at 0x2b267c262ce1
$ pstack pid
$ pstack `pgrep syslog-ng`
Backtrace for pid 21374
A syntax error in expression, near `'.
#0 0x00000034bb6cb14f in poll () from /lib64/libc.so.6
#1 0x0000000000402957 in main_context_poll (ufds=0x9b1920, nfsd=22,
timeout_=14303) at main.c:134
#2 0x00002b3ba086a90f in g_main_context_poll (context=0x966400, block=1,
dispatch=1, self=) at gmain.c:3093
#3 g_main_context_iterate (context=0x966400, block=1, dispatch=1,
self=) at gmain.c:2775
#4 0x00002b3ba086af0b in g_main_context_iteration (context=0x966400,
may_block=1) at gmain.c:2843
#5 0x0000000000402421 in main_loop_run (cfg=0x7ffff43c6040) at main.c:170
#6 0x00000000004028d9 in main (argc=1, argv=0x7ffff43c6138) at main.c:448
這個訊息跟在gdb下thread apply all bt是一樣的。$ netstat -an | grep 127.0.0.1:5432 | awk '{print $6}' | sort | uniq -c
結果: 10 CLOSE_WAIT 36 ESTABLISHED 1 LISTEN 33 TIME_WAIT
$ top -p `pgrep sshd | sed -e :x -e '$!N;s/\n/,/;tx'` # sed 的作用是把換行字元取代成","結果︰
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2198 root 16 0 90128 3308 2580 S 0.0 0.0 0:02.97 sshd 2212 test 15 0 90228 1880 1104 S 0.0 0.0 0:20.82 sshd 2224 root 16 0 90128 3308 2580 S 0.0 0.0 0:00.03 sshd
$ watch -n 1 'ls /proc/`pgrep daemon`/fd | wc -l'結果︰
Every 1.0s: ls /proc/`pgrep daemon`/fd | wc -l Mon May 16 21:01:04 2011 50
$ sed -e :x -e '$!N;s/\n/,/;tx' 或 $ sed '/^.*$/N;s/,/\n/g'
$ netstat -ntulp結果:
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2304/httpd tcp 0 0 10.32.1.10:22 0.0.0.0:* LISTEN 2110/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2136/sendmail: acce tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 2304/httpd udp 0 0 127.0.0.1:514 0.0.0.0:* 10575/syslog-ng udp 0 0 0.0.0.0:34224 0.0.0.0:* 10614/collectd
$ lsb_release -a or $ cat /etc/issue or $ cat /proc/version
$ crontab -e 或 $ vim /etc/crontab
3 4 * * * root sh /home/backup.sh 分 時 日 月 週 身份 指令上述指令為每天半夜4:03備份資料
$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/test/.ssh/id_rsa): (按enter) Enter passphrase (empty for no passphrase): (按enter) Enter same passphrase again: (按enter) Your identification has been saved in /home/test/.ssh/id_rsa. (按enter) Your public key has been saved in /home/test/.ssh/id_rsa.pub. (按enter) The key fingerprint is: fe:3f:63:3d:7d:34:06:53:a3:53:22:73:c3:c4:a3:f3 test@test-desktop.local andomart image is: +--[ RSA 2048]----+ | o+ . | | . +.E+| | . ..=.| | . o ..= . oo.| | . + = So.=. o. | | . . o ...+ | | . | | | | | +-----------------+在~/.ssh目錄下產生了id_rsa與id_rsa.pub
$ cd ~/.ssh $ scp id_rsa.pub username@server_host_name:~/.ssh
$ cd ~/.ssh $ cat id_rsa.pub >> authorized_keys $ chmod 600 authorized_keys
$ rsync -avz --delete -e ssh /home/brian/program brian@10.10.0.1:/home/brian/backup參數說明:
$ echo 6553600 >/proc/sys/net/ipv4/netfilter/ip_conntrack_max $ sysctl -w net.ipv4.ip_conntrack_max=6553600 $ vim /etc/sysctl.conf 修改 netfilter/ip_conntrack_max 這一行