問題描述:
跑一個process, 中間 fork ㄧ個 child process, 之後parent process 繼續執行, 發現child process 好像卡住, 不會繼續動作
Step1.
ulimit -c unlimited
設定 core dump file size 為unlimited, 預設值為0 size
ulimit 程式的主要目的是用來設定程式執行的許多參數, 包括 core file size, data segment size 還有許多其他的參數, 請利用 ulimit -a 來秀所有support 的參數
# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
pending signals (-i) 1024
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 1024t
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 3072
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Step2.
執行主程式, 可以看到parent process fork 出child process 的process id 為 31887 (利用 getpid()得知), 另外在 ps 也可以看到
# ps aux | grep prog
root 31886 0.1 0.4 2932 904 pts/1 S+ 00:42 0:00 ./prog
root 31887 0.0 0.4 2912 872 pts/1 S+ 00:42 0:00 ./prog
root 31888 0.0 0.4 2928 928 pts/1 S+ 00:42 0:00 ./prog
Step3.
kill -11 31887
送出 SIGSEGV signal 給 child process, child process 收到 segmentation fault 的signal, 就會 core dump 並且在同一個目錄下, 產生core.XXX (XXX為process id) 的檔案, 以這裡的例子而言就是
core.31887
/usr/include/asm/signal.h 下的定義
#define SIGSEGV 11
Step4.
利用 gdb 來debug
# gdb prog core.31887
[略]
Core was generated by `./prog'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libstdc++.so.6...done.
Loaded symbols for /usr/lib/libstdc++.so.6
Reading symbols from /lib/tls/libm.so.6...done.
Loaded symbols for /lib/tls/libm.so.6
Reading symbols from /lib/libgcc_s.so.1...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/tls/libc.so.6...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x0092e7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb) bt << 下bt (backtrace) 去 trace 所有的 function
#0 0x0092e7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1 0x00a0cfc1 in recvfrom () from /lib/tls/libc.so.6
#2 0x0804f0b7 in getMessage (fd=2048, buf=0xfef6d4a0 "\001\001", len=0xfef6cfc4, srcIp=0x800, srcPort=0x800,
verbose=false) at udp.cxx:127
#3 0x0804daf6 in MyTest (myFd=3, dest=@0x800, testNum=1, verbose=false, reply=0xfef6df18) at stun.cxx:2188
#4 0x0804a460 in get_mess (req=0xfef6df50, reqtype=QT_Reflexive, reply=0x0, type=0xfffffe00)
at myclient.cxx:632
#5 0x0804a8c6 in refresh (reqfd=3, svr=0xfef6ea60) at myclient.cxx:572
#6 0x08049299 in main (argc=1, argv=0xfef6eb24) at sip8test.c:71
因為 frame 0, 1 都是system call
frame 2, 3, 4, 5, 6 都是我們程式自己寫的 function
所以可以懷疑程式是卡在 fram 2 getMessage function 當中, 也就是 udp.cxx 的第127 行
Step5.
frame 就是有許多不同層 stack 的意思, 在gdb 中可以利用frame 去jump 到某ㄧ個特定的stack (frame), 來print variable value
(gdb) frame 2 << 我們這裡執行 frame 2 來看stack2 的variable value, 可以用 p XXX 來看
#2 0x0804f0b7 in getMessage (fd=2048, buf=0xfef6d4a0 "\001\001", len=0xfef6cfc4, srcIp=0x800, srcPort=0x800,
verbose=false) at udp.cxx:127
127 *len = recvfrom(fd,
Step6.
這時可以list 來看 code 的內容, 找出錯誤的原因
(gdb) list
122 assert( originalSize > 0 );
123
124 struct sockaddr_in from;
125 int fromLen = sizeof(from);
126
127 *len = recvfrom(fd,
128 buf,
129 originalSize,
130 0,
131 (struct sockaddr *)&from,
Embedded system debug
# toolChain_gdb daemon coreFile
For example
# /opt/v6_be_uclibc/bin/arm_v6_be_uclibc-gdb daemon coreFile
This area is my sharing area. Include some technical/believing/life experiences. Hope you can enjoy with me. God bless you. :)
2007年5月6日 星期日
2007年5月3日 星期四
p2p working group and research
Internet2 Peer to Peer Working Group - P2P WG
- [ 翻譯此頁 ]| The Internet2 End-to-End Performance Initiative (E2Epi) is aimed at improving end-to-end performance in the network infrastructure by focusing resources and efforts on improving performance problem detection and resolution throughout ... p2p.internet2.edu/ - 17k - |
OpenP2P.com -- How the Peer-to-Peer Working Group Ought to Be ...
- [ 翻譯此頁 ]| Tim O'Reilly says that Intel squandered the opportunity to kick off a real working group process at its first meeting of the Peer-to-Peer working group. www.openp2p.com/pub/a/p2p/2000/10/13/working_grp.html - 29k - |
P2P Networks
- [ 翻譯此頁 ]OpenP2P.com -- p2p development, open source development The O'Reilly Network's P2P DevCenter offers comprehensive P2P developer information. Peer-to-Peer Working Group - Home · Thoughts on Peer-to-Peer.ntrg.cs.tcd.ie/undergrad/4ba2.02-03/Intro.html - 6k -
pureftp 操作經驗
How to add a user to the pureftp
1. vi /etc/pureftpd.passwd,
新增ㄧ筆user data 在pureftpd 密碼檔當中, ㄧ般標準程序是利用
pure-pw useradd 來新增user, 這裡直接去修改 pureftpd 密碼檔比較快,
直接複製既有其他的user password, 修改username, 以及login 的directory,
david:$2a$07$zSvK1qKH4q3hWAz.E3CAEussQp29Qt/tm2vnEy:10003:100:David Lee:/home/david/./::::::::::::
/home/david/. ==> login directory 之後有一點(.)表示, login 後被 change 為只能看到login directory 以下的檔案, 不能看到整個系統的檔案
2. 新增user 之後, 再去更改該 user 的 password
pure-pw passwd david
3. 最後跑 pure-pw mkdb 即可
1. vi /etc/pureftpd.passwd,
新增ㄧ筆user data 在pureftpd 密碼檔當中, ㄧ般標準程序是利用
pure-pw useradd 來新增user, 這裡直接去修改 pureftpd 密碼檔比較快,
直接複製既有其他的user password, 修改username, 以及login 的directory,
david:$2a$07$zSvK1qKH4q3hWAz.E3CAEussQp29Qt/tm2vnEy:10003:100:David Lee:/home/david/./::::::::::::
/home/david/. ==> login directory 之後有一點(.)表示, login 後被 change 為只能看到login directory 以下的檔案, 不能看到整個系統的檔案
2. 新增user 之後, 再去更改該 user 的 password
pure-pw passwd david
3. 最後跑 pure-pw mkdb 即可
2007年5月2日 星期三
shared memory 心得
1. 每個process 都擁有自己的4G virtual memory, 而實際對應到真正的 physically memory, 則是靠kernel 的 Memory management unit 來做處理, 所以在不同的process 之間所看到的同樣位址(virtual address), 實際對應到memory 的 physical address (linear address) 並不相同
2. 如果是 shared memory 則在不同的 process 所看到的 shared memory virtual address 則會對應到同一個physical address
2. 如果是 shared memory 則在不同的 process 所看到的 shared memory virtual address 則會對應到同一個physical address
destroy_conntrack 的call 法
destroy_conntrack 的call 法如下
net/ipv4/netfilter/ip_conntrack_core.c
inline void
ip_conntrack_put(struct ip_conntrack *ct)
{
IP_NF_ASSERT(ct);
nf_conntrack_put(&ct->ct_general);
}
ip_conntrack_put(struct ip_conntrack *ct)
{
IP_NF_ASSERT(ct);
nf_conntrack_put(&ct->ct_general);
}
include/linux/skbuff.h
static inline void nf_conntrack_put(struct nf_conntrack *nfct)
{
if (nfct && atomic_dec_and_test(&nfct->use))
nfct->destroy(nfct);
}
{
if (nfct && atomic_dec_and_test(&nfct->use))
nfct->destroy(nfct);
}
因為在 init_conntrack 時, 有做 use 的atomic set 動作, 所以必須call ip_conntrack_put 來
作 decrease use 的動作
net/ipv4/netfilter/ip_conntrack_core.c
init_conntrack(const struct ip_conntrack_tuple *tuple,
struct ip_conntrack_protocol *protocol,
struct sk_buff *skb) {
struct ip_conntrack_protocol *protocol,
struct sk_buff *skb) {
..
[略]
atomic_set(&conntrack->ct_general.use, 1);
conntrack->ct_general.destroy = destroy_conntrack;
conntrack->ct_general.destroy = destroy_conntrack;
2007年5月1日 星期二
shared memory
顯示系統目前的 shared memory
# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x0000162e 65536 root 666 27 0
0x00000000 98305 root 666 192 0
0x00001234 163843 root 666 192 0
刪除某ㄧ個特定的 shared memory key
# ipcrm -M 0x0000162e
原先的 shared memory 0x0000162e 已經被刪除了
# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 98305 root 666 192 0
0x00001234 163843 root 666 192 0
# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x0000162e 65536 root 666 27 0
0x00000000 98305 root 666 192 0
0x00001234 163843 root 666 192 0
刪除某ㄧ個特定的 shared memory key
# ipcrm -M 0x0000162e
原先的 shared memory 0x0000162e 已經被刪除了
# ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 98305 root 666 192 0
0x00001234 163843 root 666 192 0
如何傳遞陣列指標(function variable) 在函數中
#include
#include
#include
struct abc {
int val;
char str[10];
};
void allocatemem(void*** a1) {
int amount;
printf("s1 - &a1: %10p, a1: %10p, *a1: %10p\n", a1, *a1, **a1);
amount = sizeof(struct abc)*16;
if ((*a1=(void**)malloc(amount))==NULL) {
printf("errno: %s, desc: %s\n", errno, strerror(errno));
}
printf("s2 - &a1: %10p, a1: %10p, *a1: %10p\n", a1, *a1, **a1);
memset(*a1, 0, amount);
//printf("memset ok\n");
printf("s4 - &a1: %10p, a1: %10p, *a1: %10p\n", a1, *a1, **a1);
}
void filldata(struct abc (*aa)[16]) {
printf("s6 - &aa: %10p, aa: %10p, *aa: %10p, &(*aa)[0]: %10p, &(*aa)[1]: %10p\n", &aa, aa, *aa, &(*aa)[0], &(*aa)[1]);
(*aa)[0].val = 0;
strcpy((*aa)[0].str, "hello0");
printf("aa[0] ok\n");
(*aa[1]).val = 1;
strcpy((*aa[1]).str, "hello1");
printf("aa[1] ok\n");
}
int main(int argc, char** argv) {
struct abc (*a1)[16];
printf("s0 - &a1: %10p, a1: %10p, *a1: %10p, &(*a1)[0]: %10p, &(*a1)[1]: %10p\n", &a1, a1, *a1, &(*a1)[0], &(*a1)[1]);
allocatemem((void***)&a1);
printf("s5 - &a1: %10p, a1: %10p, *a1: %10p, &(*a1)[0]: %10p, &(*a1)[1]: %10p\n", &a1, a1, *a1, &(*a1)[0], &(*a1)[1]);
filldata(a1);
return 0;
}
# gcc -o a5 ./array5.c
# ./a5
s0 - &a1: 0xfeee4444, a1: 0x943c80, *a1: 0x943c80, &(*a1)[0]: 0x943c80, &(*a1)[1]: 0x943c90
s1 - &a1: 0xfeee4444, a1: 0x943c80, *a1: (nil)
s2 - &a1: 0xfeee4444, a1: 0x8820008, *a1: (nil)
s4 - &a1: 0xfeee4444, a1: 0x8820008, *a1: (nil)
s5 - &a1: 0xfeee4444, a1: 0x8820008, *a1: 0x8820008, &(*a1)[0]: 0x8820008, &(*a1)[1]: 0x8820018
s6 - &aa: 0xfeee4420, aa: 0x8820008, *aa: 0x8820008, &(*aa)[0]: 0x8820008, &(*aa)[1]: 0x8820018
aa[0] ok
aa[1] ok
#include
#include
struct abc {
int val;
char str[10];
};
void allocatemem(void*** a1) {
int amount;
printf("s1 - &a1: %10p, a1: %10p, *a1: %10p\n", a1, *a1, **a1);
amount = sizeof(struct abc)*16;
if ((*a1=(void**)malloc(amount))==NULL) {
printf("errno: %s, desc: %s\n", errno, strerror(errno));
}
printf("s2 - &a1: %10p, a1: %10p, *a1: %10p\n", a1, *a1, **a1);
memset(*a1, 0, amount);
//printf("memset ok\n");
printf("s4 - &a1: %10p, a1: %10p, *a1: %10p\n", a1, *a1, **a1);
}
void filldata(struct abc (*aa)[16]) {
printf("s6 - &aa: %10p, aa: %10p, *aa: %10p, &(*aa)[0]: %10p, &(*aa)[1]: %10p\n", &aa, aa, *aa, &(*aa)[0], &(*aa)[1]);
(*aa)[0].val = 0;
strcpy((*aa)[0].str, "hello0");
printf("aa[0] ok\n");
(*aa[1]).val = 1;
strcpy((*aa[1]).str, "hello1");
printf("aa[1] ok\n");
}
int main(int argc, char** argv) {
struct abc (*a1)[16];
printf("s0 - &a1: %10p, a1: %10p, *a1: %10p, &(*a1)[0]: %10p, &(*a1)[1]: %10p\n", &a1, a1, *a1, &(*a1)[0], &(*a1)[1]);
allocatemem((void***)&a1);
printf("s5 - &a1: %10p, a1: %10p, *a1: %10p, &(*a1)[0]: %10p, &(*a1)[1]: %10p\n", &a1, a1, *a1, &(*a1)[0], &(*a1)[1]);
filldata(a1);
return 0;
}
# gcc -o a5 ./array5.c
# ./a5
s0 - &a1: 0xfeee4444, a1: 0x943c80, *a1: 0x943c80, &(*a1)[0]: 0x943c80, &(*a1)[1]: 0x943c90
s1 - &a1: 0xfeee4444, a1: 0x943c80, *a1: (nil)
s2 - &a1: 0xfeee4444, a1: 0x8820008, *a1: (nil)
s4 - &a1: 0xfeee4444, a1: 0x8820008, *a1: (nil)
s5 - &a1: 0xfeee4444, a1: 0x8820008, *a1: 0x8820008, &(*a1)[0]: 0x8820008, &(*a1)[1]: 0x8820018
s6 - &aa: 0xfeee4420, aa: 0x8820008, *aa: 0x8820008, &(*aa)[0]: 0x8820008, &(*aa)[1]: 0x8820018
aa[0] ok
aa[1] ok
訂閱:
文章 (Atom)