10.1假期前学习了gtk4,粗通后准备改造一下张老师的程序:
https://github.com/gedulab/silklock/blob/main/silklock.cpp
这个程序我看是2023年上传的,用的是gtk2,在我的机器上死活跑不起来,界面直接死掉退出。估计是我的ubuntu版本太新了,运行gtk2有问题。假期出去几天,10.6开始在家休息两天,这两天仔细研究了这个程序,终于将gtk2迁移改造为gtk4,可以在我的ubuntu 上运行了。不过有个缺点,就是界面不能换行,加了\n就运行异常,估计还是没有学好gtk4。这也不影响使用GDB调试这个多线程程序,让我们开始结合这个slock.cpp(我缩短了文件名称)来操练gdb多线程调试吧。
(gdb) bt
#0 0x00007f41b087b4cd in __GI___poll (fds=0x556a36a2dcd0, nfds=2, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
#1 0x00007f41b0cda66e in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2 0x00007f41b0c7aa53 in g_main_context_iteration () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3 0x00007f41b0eb188d in g_application_run () at /lib/x86_64-linux-gnu/libgio-2.0.so.0
#4 0x0000556a2e364efd in main (argc=1, argv=0x7ffdcfcba138) at slock.cpp:139
这个线程是UI线程,UI线程当前执行到了GI_poll
(gdb) info args --info看参数
fds = 0x556a36a2dcd0
nfds = 2
timeout = -1
(gdb) p fds --print看变量
$1 = (struct pollfd *) 0x556a36a2dcd0
(gdb) pt fds --pt看类型
type = struct pollfd {
int fd;
short events;
short revents;
} *
(gdb) p fds[0]@2 --print数组的前2个
$2 = {{fd = 3, events = 1, revents = 0}, {fd = 8, events = 1, revents = 0}}
其中的fd=3,fd=8是什么?可以通过lsof来获取
进程ID是30133
(gdb) !lsof -p 30133 --列出打开的文件描述符
lsof: WARNING: can't stat() fuse.portal file system /run/user/1001/doc
Output information may be incomplete.
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1001/gvfs
Output information may be incomplete.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
slock 30133 zxl 3u a_inode 0,14 0 13557 [eventfd:165]
slock 30133 zxl 4u a_inode 0,14 0 13557 [eventfd:166]
slock 30133 zxl 5u unix 0xffff8de34994e600 0t0 174584 type=STREAM (CONNECTED)
slock 30133 zxl 6u a_inode 0,14 0 13557 [eventfd:167]
slock 30133 zxl 7r a_inode 0,14 0 13557 inotify
slock 30133 zxl 8u IPv4 174590 0t0 TCP localhost:33258->localhost:6010 (ESTABLISHED)
3号和8号文件描述符上面标红了。eventfd就是事件使用的,比如鼠标键盘事件。UI程序是比较复杂的,要处理这种事件。
这个UI线程在等消息,没有啥问题,下面继续看其他线程:
(gdb) info threads
Id Target Id Frame
* 1 Thread 0x7f41af756e40 (LWP 30133) "slock" 0x00007f41b087b4cd in __GI___poll (fds=0x556a36a2dcd0, nfds=2,
timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
2 Thread 0x7f414e7fc6c0 (LWP 30177) "slock" 0x0000556a2e3654a8 in MasterThreadProc (p=0x556a2e36c0a0 <boss>)
at boxboss.cpp:122
3 Thread 0x7f412dffb6c0 (LWP 30175) "slock" futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
4 Thread 0x7f412effd6c0 (LWP 30173) "slock" futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
5 Thread 0x7f412f7fe6c0 (LWP 30172) "slock" futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
6 Thread 0x7f412ffff6c0 (LWP 30171) "slock" (Exiting) futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
7 Thread 0x7f414dffb6c0 (LWP 30168) "slock" futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
8 Thread 0x7f416f7fe6c0 (LWP 30167) "slock" futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
9 Thread 0x7f416ffff6c0 (LWP 30146) "slock:disk$0" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (private=0,
cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e6b4d38) at ./nptl/futex-internal.c:57
10 Thread 0x7f418cc246c0 (LWP 30145) "slock" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (
private=32577, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e76e8d0) at ./nptl/futex-internal.c:57
11 Thread 0x7f418d4256c0 (LWP 30144) "slock" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (
private=32577, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e76e8d0) at ./nptl/futex-internal.c:57
12 Thread 0x7f418dc266c0 (LWP 30143) "slock" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (
private=32577, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e76e8d0) at ./nptl/futex-internal.c:57
13 Thread 0x7f418e4276c0 (LWP 30142) "slock" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (
private=32577, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e76e8d0) at ./nptl/futex-internal.c:57
14 Thread 0x7f418ec286c0 (LWP 30141) "llvmpipe-3" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (private=0,
cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e75f628) at ./nptl/futex-internal.c:57
15 Thread 0x7f419cbff6c0 (LWP 30140) "llvmpipe-2" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (private=0,
cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e75f4cc) at ./nptl/futex-internal.c:57
16 Thread 0x7f419d4006c0 (LWP 30139) "llvmpipe-1" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (private=0,
cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e75f368) at ./nptl/futex-internal.c:57
17 Thread 0x7f419dc016c0 (LWP 30138) "llvmpipe-0" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (private=0,
cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e75f208) at ./nptl/futex-internal.c:57
18 Thread 0x7f41ad6926c0 (LWP 30137) "slock" syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
19 Thread 0x7f41ade936c0 (LWP 30136) "gdbus" 0x00007f41b087b4cd in __GI___poll (fds=0x7f41a4000b90, nfds=3,
--Type <RET> for more, q to quit, c to continue without paging--
timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
20 Thread 0x7f41ae6b56c0 (LWP 30135) "gmain" 0x00007f41b087b4cd in __GI___poll (fds=0x556a2e6c08e0, nfds=2,
timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
21 Thread 0x7f41aeeb66c0 (LWP 30134) "pool-spawner" syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
21个线程,3种状态:
- Poll
- wait
- 正在跑
正在跑的只有2号线程,切换到2号线程,list看看:
(gdb) thread 2
[Switching to thread 2 (Thread 0x7f414e7fc6c0 (LWP 30177))]
#0 0x0000556a2e3654a8 in MasterThreadProc (p=0x556a2e36c0a0 <boss>) at boxboss.cpp:122
122 while(pBoss->m_dwThreadCount != pBoss->m_dwCalcThreads) {
(gdb) l
117 uint32_t MasterThreadProc(void* p) {
118 CBoxBoss *pBoss = (CBoxBoss *)p;
119 uint32_t i;
120 d4d(_T("Master thread entered..."));
121
122 while(pBoss->m_dwThreadCount != pBoss->m_dwCalcThreads) {
123
124 }
125 pBoss->m_dResult = 0;
126 for(i=0;i<pBoss->m_dwCalcThreads;i++) {
(gdb) bt
#0 0x0000556a2e3654a8 in MasterThreadProc (p=0x556a2e36c0a0 <boss>) at boxboss.cpp:122
#1 0x0000556a2e36774f in std::__invoke_impl<unsigned int, unsigned int (*)(void*), CBoxBoss*>
(__f=@0x556a374c2a00: 0x556a2e36546d <MasterThreadProc(void*)>) at /usr/include/c++/13/bits/invoke.h:61
#2 0x0000556a2e367624 in std::__invoke<unsigned int (*)(void*), CBoxBoss*>
(__fn=@0x556a374c2a00: 0x556a2e36546d <MasterThreadProc(void*)>) at /usr/include/c++/13/bits/invoke.h:96
#3 0x0000556a2e367537 in std::thread::_Invoker<std::tuple<unsigned int (*)(void*), CBoxBoss*> >::_M_invoke<0ul, 1ul>
(this=0x556a374c29f8) at /usr/include/c++/13/bits/std_thread.h:292
#4 0x0000556a2e3674d0 in std::thread::_Invoker<std::tuple<unsigned int (*)(void*), CBoxBoss*> >::operator()
(this=0x556a374c29f8) at /usr/include/c++/13/bits/std_thread.h:299
#5 0x0000556a2e36748c in std::thread::_State_impl<std::thread::_Invoker<std::tuple<unsigned int (*)(void*), CBoxBoss*> > >::_M_run (this=0x556a374c29f0) at /usr/include/c++/13/bits/std_thread.h:244
#6 0x00007f41b0a8bbb4 in ??? () at /lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007f41b07fca94 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#8 0x00007f41b0889c3c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
使用的是C++11的std::thread启动的线程。最后调用了我们的线程入口MasterThreadProc
(gdb) l MasterThreadProc(void*)
112 ret = -2;
113 }
114 return ret;
115 }
116
117 uint32_t MasterThreadProc(void* p) {
118 CBoxBoss *pBoss = (CBoxBoss *)p;
119 uint32_t i;
120 d4d(_T("Master thread entered..."));
121
(gdb)
122 while(pBoss->m_dwThreadCount != pBoss->m_dwCalcThreads) {
123
124 }
这个线程在busy wait,不停的比较线程数是否等于计算线程数。这两个变量都是boss对象的,那下面就观察一下变量:
(gdb) info locals
pBoss = 0x556a2e36c0a0 <boss>
i = 32577
(gdb) p *pBoss
$3 = {_vptr.CBoxBoss = 0x556a2e36bb28 <vtable for CBoxBoss+16>,
m_vecWorkerThreads = std::vector of length 20, capacity 32 = {{_M_id = {_M_thread = 139918827321024}}, {_M_id = {
_M_thread = 139918818928320}}, {_M_id = {_M_thread = 139918810535616}}, {_M_id = {_M_thread = 139918802142912}}, {
_M_id = {_M_thread = 139918793750208}}, {_M_id = {_M_thread = 139918785357504}}, {_M_id = {
_M_thread = 139918776964800}}, {_M_id = {_M_thread = 139918491776704}}, {_M_id = {_M_thread = 139918483384000}}, {
_M_id = {_M_thread = 139918474991296}}, {_M_id = {_M_thread = 139919020254912}}, {_M_id = {
_M_thread = 139918458205888}}, {_M_id = {_M_thread = 139918449813184}}, {_M_id = {_M_thread = 139918441420480}}, {
_M_id = {_M_thread = 139917954905792}}, {_M_id = {_M_thread = 139917946513088}}, {_M_id = {
_M_thread = 139917938120384}}, {_M_id = {_M_thread = 139917929727680}}, {_M_id = {_M_thread = 139917921334976}}, {
_M_id = {_M_thread = 139917912942272}}}, m_pMasterThread = 0x556a3739f190, m_CountLock = {<std::__mutex_base> = {
_M_mutex = {__data = {__lock = 2, __count = 0, __owner = 30174, __nusers = 1, __kind = 0, __spins = 0, __elision = 0,
__list = {__prev = 0x0, __next = 0x0}},
__size = "\002\000\000\000\000\000\000\000\336u\000\000\001", '\000' <repeats 26 times>,
__align = 2}}, <No data fields>}, m_dwThreadCount = 4, m_dwCalcThreads = 10, m_dwSeriesMemberCount = 10000,
m_pThreadParams = 0x556a37385380, m_pSums = 0x556a37752b10, m_dXtoCalc = 1, m_dResult = 0.69309718305995138,
m_bQuitRoguish = false, m_bNeedNotify = true, m_nDoorBells = {0, 0, 1, 1, 0, 0}, m_pChairMan = 0x556a00000001}
10个线程,只有4个完成,还有6个未完成。正好有6个线程处于futex_wait,那这6个线程在做什么?继续观察线程堆栈:
(gdb) thread apply all bt
Thread 21 (Thread 0x7f41aeeb66c0 (LWP 30134) "pool-spawner"):
#0 syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1 0x00007f41b0cd440d in g_cond_wait () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2 0x00007f41b0c4552b in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3 0x00007f41b0cad043 in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4 0x00007f41b0ca9c82 in ??? () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5 0x00007f41b07fca94 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#6 0x00007f41b0889c3c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
。。。。。。
Thread 4 (Thread 0x7f412effd6c0 (LWP 30173) "slock"):
#0 futex_wait (private=0, expected=2, futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
#1 __GI___lll_lock_wait (futex=futex@entry=0x556a2e36c0c8 <boss+40>, private=0) at ./nptl/lowlevellock.c:49
#2 0x00007f41b08000f1 in lll_mutex_lock_optimized (mutex=0x556a2e36c0c8 <boss+40>) at ./nptl/pthread_mutex_lock.c:48
#3 ___pthread_mutex_lock (mutex=0x556a2e36c0c8 <boss+40>) at ./nptl/pthread_mutex_lock.c:93
#4 0x0000556a2e3659df in __gthread_mutex_lock (__mutex=0x556a2e36c0c8 <boss+40>) at /usr/include/x86_64-linux-gnu/c++/13/bits/gthr-default.h:749
#5 0x0000556a2e365b88 in std::mutex::lock (this=0x556a2e36c0c8 <boss+40>) at /usr/include/c++/13/bits/std_mutex.h:113
#6 0x0000556a2e3652f5 in ParallelCalc (pParam=0x556a373853e0) at boxboss.cpp:80
#7 0x0000556a2e36541d in CalcThreadProc (p=0x556a373853e0) at boxboss.cpp:109
#8 0x0000556a2e3677c9 in std::__invoke_impl<unsigned int, unsigned int (*)(void*), _THREADPARAM*> (__f=@0x556a37910990: 0x556a2e365392 <CalcThreadProc(void*)>) at /usr/include/c++/13/bits/invoke.h:61
#9 0x0000556a2e3676c3 in std::__invoke<unsigned int (*)(void*), _THREADPARAM*> (__fn=@0x556a37910990: 0x556a2e365392 <CalcThreadProc(void*)>) at /usr/include/c++/13/bits/invoke.h:96
#10 0x0000556a2e367585 in std::thread::_Invoker<std::tuple<unsigned int (*)(void*), _THREADPARAM*> >::_M_invoke<0ul, 1ul> (this=0x556a37910988) at /usr/include/c++/13/bits/std_thread.h:292
#11 0x0000556a2e3674ee in std::thread::_Invoker<std::tuple<unsigned int (*)(void*), _THREADPARAM*> >::operator() (this=0x556a37910988) at /usr/include/c++/13/bits/std_thread.h:299
#12 0x0000556a2e3674b0 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<unsigned int (*)(void*), _THREADPARAM*> > >::_M_run (this=0x556a37910980) at /usr/include/c++/13/bits/std_thread.h:244
#13 0x00007f41b0a8bbb4 in ??? () at /lib/x86_64-linux-gnu/libstdc++.so.6
#14 0x00007f41b07fca94 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#15 0x00007f41b0889c3c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
。。。。。。
6个线程都调用lock加锁时卡住了。都是试图获取锁时拿不到。拿一个线程做代表,比如就分析这个thread 4。thread 4切换过去,bt,然后先分析自己的代码,比如到7号栈帧CalcThreadProc,时光倒流:
(gdb) frame 7
#7 0x0000556a2e36541d in CalcThreadProc (p=0x556a373853e0) at boxboss.cpp:109
109 ParallelCalc(pParam);
(gdb) l
104 d4d("bad exception occurred, log and quit");
105 return -1;
106 }
107 #endif
108 try {
109 ParallelCalc(pParam);
110 } catch(...) {
111 d4d("bad exception occurred,log and quit");
112 ret = -2;
113 }
(gdb) frame 6
#6 0x0000556a2e3652f5 in ParallelCalc (pParam=0x556a373853e0) at boxboss.cpp:80
80 pParam->pBoss->m_CountLock.lock();
(gdb) l
75
76 pParam->pBoss->m_pSums[nThreadIndex]=0;
77 for(int i=nThreadIndex;i<nSeriesMemberCount;i+=nNumThreads) {
78 pParam->pBoss->m_pSums[nThreadIndex]+=GetMember(i+1,x);
79 }
80 pParam->pBoss->m_CountLock.lock();
81 pParam->pBoss->m_dwThreadCount++;
82 dwWait = 100000;
83 sleep(1);
计算完成了,要做总数++,多线程环境,需要用锁保护。那为啥获取不到锁呢?继续分析:
(gdb) bt
#0 futex_wait (private=0, expected=2, futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
#1 __GI___lll_lock_wait (futex=futex@entry=0x556a2e36c0c8 <boss+40>, private=0) at ./nptl/lowlevellock.c:49
#2 0x00007f41b08000f1 in lll_mutex_lock_optimized (mutex=0x556a2e36c0c8 <boss+40>) at ./nptl/pthread_mutex_lock.c:48
#3 ___pthread_mutex_lock (mutex=0x556a2e36c0c8 <boss+40>) at ./nptl/pthread_mutex_lock.c:93
#4 0x0000556a2e3659df in __gthread_mutex_lock (__mutex=0x556a2e36c0c8 <boss+40>)
at /usr/include/x86_64-linux-gnu/c++/13/bits/gthr-default.h:749
#5 0x0000556a2e365b88 in std::mutex::lock (this=0x556a2e36c0c8 <boss+40>) at /usr/include/c++/13/bits/std_mutex.h:113
lll是low level lock的简称,是GNU基础库的一部分。linux的线程库叫pthread,pthread的一部分就是底层锁。
(gdb) frame 2
#2 0x00007f41b08000f1 in lll_mutex_lock_optimized (mutex=0x556a2e36c0c8 <boss+40>) at ./nptl/pthread_mutex_lock.c:48
warning: 48 ./nptl/pthread_mutex_lock.c: 没有那个文件或目录
(gdb) info args
mutex = 0x556a2e36c0c8 <boss+40>
(gdb) pt mutex
type = union {
struct __pthread_mutex_s __data;
char __size[40];
long __align;
} *
(gdb) p *mutex
$4 = {__data = {__lock = 2, __count = 0, __owner = 30174, __nusers = 1, __kind = 0, __spins = 0, __elision = 0, __list = {
__prev = 0x0, __next = 0x0}}, __size = "\002\000\000\000\000\000\000\000\336u\000\000\001", '\000' <repeats 26 times>,
__align = 2}
检查死锁的步骤:找到线程,切换线程,找到lll栈帧,时光倒流到这栈帧,然后打印锁的内容,找到关键的owner.
30174是线程ID,找一下有没有这个线程:
(gdb) info threads
Id Target Id Frame
1 Thread 0x7f41af756e40 (LWP 30133) "slock" 0x00007f41b087b4cd in __GI___poll (fds=0x556a36a2dcd0, nfds=2,
timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
2 Thread 0x7f414e7fc6c0 (LWP 30177) "slock" 0x0000556a2e3654a8 in MasterThreadProc (p=0x556a2e36c0a0 <boss>)
at boxboss.cpp:122
3 Thread 0x7f412dffb6c0 (LWP 30175) "slock" futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
* 4 Thread 0x7f412effd6c0 (LWP 30173) "slock" futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
5 Thread 0x7f412f7fe6c0 (LWP 30172) "slock" futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
6 Thread 0x7f412ffff6c0 (LWP 30171) "slock" (Exiting) futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
7 Thread 0x7f414dffb6c0 (LWP 30168) "slock" futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
8 Thread 0x7f416f7fe6c0 (LWP 30167) "slock" futex_wait (private=0, expected=2,
futex_word=0x556a2e36c0c8 <boss+40>) at ../sysdeps/nptl/futex-internal.h:146
9 Thread 0x7f416ffff6c0 (LWP 30146) "slock:disk$0" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (private=0,
cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e6b4d38) at ./nptl/futex-internal.c:57
10 Thread 0x7f418cc246c0 (LWP 30145) "slock" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (
private=32577, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e76e8d0) at ./nptl/futex-internal.c:57
11 Thread 0x7f418d4256c0 (LWP 30144) "slock" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (
private=32577, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e76e8d0) at ./nptl/futex-internal.c:57
12 Thread 0x7f418dc266c0 (LWP 30143) "slock" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (
private=32577, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e76e8d0) at ./nptl/futex-internal.c:57
13 Thread 0x7f418e4276c0 (LWP 30142) "slock" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (
private=32577, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e76e8d0) at ./nptl/futex-internal.c:57
14 Thread 0x7f418ec286c0 (LWP 30141) "llvmpipe-3" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (private=0,
cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e75f628) at ./nptl/futex-internal.c:57
15 Thread 0x7f419cbff6c0 (LWP 30140) "llvmpipe-2" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (private=0,
cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e75f4cc) at ./nptl/futex-internal.c:57
16 Thread 0x7f419d4006c0 (LWP 30139) "llvmpipe-1" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (private=0,
cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e75f368) at ./nptl/futex-internal.c:57
17 Thread 0x7f419dc016c0 (LWP 30138) "llvmpipe-0" 0x00007f41b07f8d61 in __futex_abstimed_wait_common64 (private=0,
cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x556a2e75f208) at ./nptl/futex-internal.c:57
18 Thread 0x7f41ad6926c0 (LWP 30137) "slock" syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
19 Thread 0x7f41ade936c0 (LWP 30136) "gdbus" 0x00007f41b087b4cd in __GI___poll (fds=0x7f41a4000b90, nfds=3,
--Type <RET> for more, q to quit, c to continue without paging--
timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
20 Thread 0x7f41ae6b56c0 (LWP 30135) "gmain" 0x00007f41b087b4cd in __GI___poll (fds=0x556a2e6c08e0, nfds=2,
timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
21 Thread 0x7f41aeeb66c0 (LWP 30134) "pool-spawner" syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
21个线程,没有这个30174,怎么办?可能这个线程已经退出了。没有机会释放这个锁了。
现在已经没法找了,就用gdb重新加载重新跑一遍,找到这个线程。
gdb ./slock
跑动中出现了段错误:
Thread 35 "slock" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fff6ffff6c0 (LWP 31944)]
0x00005555555598d6 in ChairMan::Notify (this=0x15555e148, worker_id=8, notice=1) at chairman.cpp:9
9 this->m_nNoticeCounter++;
狐狸尾巴终于露出来了。
(gdb) bt
#0 0x00005555555598d6 in ChairMan::Notify (this=0x15555e148, worker_id=8, notice=1) at chairman.cpp:9
#1 0x00005555555570eb in CBoxBoss::Notify (this=0x55555555e0a0 <boss>, thread_id=8, notice=1) at boxboss.cpp:36
#2 0x000055555555735e in ParallelCalc (pParam=0x55555d996c20) at boxboss.cpp:87
#3 0x000055555555741d in CalcThreadProc (p=0x55555d996c20) at boxboss.cpp:109
#4 0x00005555555597c9 in std::__invoke_impl<unsigned int, unsigned int (*)(void*), _THREADPARAM*>
(__f=@0x55555e63a870: 0x555555557392 <CalcThreadProc(void*)>) at /usr/include/c++/13/bits/invoke.h:61
#5 0x00005555555596c3 in std::__invoke<unsigned int (*)(void*), _THREADPARAM*>
(__fn=@0x55555e63a870: 0x555555557392 <CalcThreadProc(void*)>) at /usr/include/c++/13/bits/invoke.h:96
#6 0x0000555555559585 in std::thread::_Invoker<std::tuple<unsigned int (*)(void*), _THREADPARAM*> >::_M_invoke<0ul, 1ul>
(this=0x55555e63a868) at /usr/include/c++/13/bits/std_thread.h:292
#7 0x00005555555594ee in std::thread::_Invoker<std::tuple<unsigned int (*)(void*), _THREADPARAM*> >::operator()
(this=0x55555e63a868) at /usr/include/c++/13/bits/std_thread.h:299
#8 0x00005555555594b0 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<unsigned int (*)(void*), _THREADPARAM*> > >::_M_run (this=0x55555e63a860) at /usr/include/c++/13/bits/std_thread.h:244
#9 0x00007ffff6f62bb4 in ??? () at /lib/x86_64-linux-gnu/libstdc++.so.6
#10 0x00007ffff6cd3a94 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#11 0x00007ffff6d60c3c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
这个出段错误的线程,估计是退出的那个线程。
(gdb) p boss
$1 = {_vptr.CBoxBoss = 0x55555555db28 <vtable for CBoxBoss+16>,
m_vecWorkerThreads = std::vector of length 20, capacity 32 = {{_M_id = {_M_thread = 140736280393408}}, {_M_id = {
_M_thread = 140736244119232}}, {_M_id = {_M_thread = 140736235726528}}, {_M_id = {_M_thread = 140736227333824}}, {
_M_id = {_M_thread = 140735743522496}}, {_M_id = {_M_thread = 140735735129792}}, {_M_id = {
_M_thread = 140735726737088}}, {_M_id = {_M_thread = 140735718344384}}, {_M_id = {_M_thread = 140735709951680}}, {
_M_id = {_M_thread = 140735701558976}}, {_M_id = {_M_thread = 140736389433024}}, {_M_id = {
_M_thread = 140735206651584}}, {_M_id = {_M_thread = 140735198258880}}, {_M_id = {_M_thread = 140735189866176}}, {
_M_id = {_M_thread = 140735181473472}}, {_M_id = {_M_thread = 140735173080768}}, {_M_id = {
_M_thread = 140735164688064}}, {_M_id = {_M_thread = 140735156295360}}, {_M_id = {_M_thread = 140735072433856}}, {
_M_id = {_M_thread = 140735064041152}}}, m_pMasterThread = 0x55555e237130, m_CountLock = {<std::__mutex_base> = {
_M_mutex = {__data = {__lock = 2, __count = 0, __owner = 31944, __nusers = 1, __kind = 0, __spins = 0, __elision = 0,
__list = {__prev = 0x0, __next = 0x0}},
__size = "\002\000\000\000\000\000\000\000\310|\000\000\001", '\000' <repeats 26 times>,
__align = 2}}, <No data fields>}, m_dwThreadCount = 3, m_dwCalcThreads = 10, m_dwSeriesMemberCount = 10000,
m_pThreadParams = 0x55555d996ba0, m_pSums = 0x55555e65e710, m_dXtoCalc = 1, m_dResult = 0.69309718305995138,
m_bQuitRoguish = false, m_bNeedNotify = true, m_nDoorBells = {1, 1, 1, 0, 0, 0}, m_pChairMan = 0x15555e148}
(gdb) info threads
Id Target Id Frame
* 35 Thread 0x7fff6ffff6c0 (LWP 31944) "slock" 0x00005555555598d6 in ChairMan::Notify (this=0x15555e148,
worker_id=8, notice=1) at chairman.cpp:9
(gdb) l
4 ChairMan::ChairMan() {
5 this->m_nNoticeCounter = 0;
6 }
7 void ChairMan::Notify(int worker_id, int notice) {
8 d4d("chairmane got notice %d from worker %d", notice,worker_id);
9 this->m_nNoticeCounter++;
10 }
这行代码为何出现段错误?这种简单代码出意外,很可能是对象指针有问题。
(gdb) p this
$2 = (ChairMan * const) 0x15555e148
这个指针被破坏了吗?
(gdb) frame 1
#1 0x00005555555570eb in CBoxBoss::Notify (this=0x55555555e0a0 <boss>, thread_id=8, notice=1) at boxboss.cpp:36
36 m_pChairMan->Notify(thread_id,notice);
(gdb) p /x $eax
$4 = 0x5555e148
eax传递的是this指针。在arm平台是x0寄存器
(gdb) p boss
$5 = {_vptr.CBoxBoss = 0x55555555db28 <vtable for CBoxBoss+16>,
m_vecWorkerThreads = std::vector of length 20, capacity 32 = {{_M_id = {_M_thread = 140736280393408}}, {_M_id = {
_M_thread = 140736244119232}}, {_M_id = {_M_thread = 140736235726528}}, {_M_id = {_M_thread = 140736227333824}}, {
_M_id = {_M_thread = 140735743522496}}, {_M_id = {_M_thread = 140735735129792}}, {_M_id = {
_M_thread = 140735726737088}}, {_M_id = {_M_thread = 140735718344384}}, {_M_id = {_M_thread = 140735709951680}}, {
_M_id = {_M_thread = 140735701558976}}, {_M_id = {_M_thread = 140736389433024}}, {_M_id = {
_M_thread = 140735206651584}}, {_M_id = {_M_thread = 140735198258880}}, {_M_id = {_M_thread = 140735189866176}}, {
_M_id = {_M_thread = 140735181473472}}, {_M_id = {_M_thread = 140735173080768}}, {_M_id = {
_M_thread = 140735164688064}}, {_M_id = {_M_thread = 140735156295360}}, {_M_id = {_M_thread = 140735072433856}}, {
_M_id = {_M_thread = 140735064041152}}}, m_pMasterThread = 0x55555e237130, m_CountLock = {<std::__mutex_base> = {
_M_mutex = {__data = {__lock = 2, __count = 0, __owner = 31944, __nusers = 1, __kind = 0, __spins = 0, __elision = 0,
__list = {__prev = 0x0, __next = 0x0}},
__size = "\002\000\000\000\000\000\000\000\310|\000\000\001", '\000' <repeats 26 times>,
__align = 2}}, <No data fields>}, m_dwThreadCount = 3, m_dwCalcThreads = 10, m_dwSeriesMemberCount = 10000,
m_pThreadParams = 0x55555d996ba0, m_pSums = 0x55555e65e710, m_dXtoCalc = 1, m_dResult = 0.69309718305995138,
m_bQuitRoguish = false, m_bNeedNotify = true, m_nDoorBells = {1, 1, 1, 0, 0, 0}, m_pChairMan = 0x15555e148}
这时已经被破坏了,只能再跑一次,提前埋伏一个断点:
(gdb) watch boss.m_pChairMan
Hardware watchpoint 1: boss.m_pChairMan
敲r重新跑
Hardware watchpoint 1: boss.m_pChairMan
Old value = (ChairMan *) 0x0
New value = (ChairMan *) 0x55555555e148 <chair>
CBoxBoss::Setup (this=0x55555555e0a0 <boss>, pChairMan=0x55555555e148 <chair>) at boxboss.cpp:27
27 return 0;
(gdb)
这是命中了,第一次变化,这是有效的,从0变成一个有效值。
(gdb) l
22 Cleanup();
23 }
24
25 int CBoxBoss::Setup(ChairMan *pChairMan) {
26 m_pChairMan = pChairMan;
27 return 0;
28 }
29
30 bool CBoxBoss::GetSettings(ADVSETTING *pSettings) {
31 return false;
这次是调用setup方法,第一次赋值。
(gdb) bt
#0 CBoxBoss::Setup (this=0x55555555e0a0 <boss>, pChairMan=0x55555555e148 <chair>) at boxboss.cpp:27
#1 0x0000555555556e80 in main (argc=1, argv=0x7fffffffe178) at slock.cpp:132
这是合理的,在main函数将chairman的指针传给了boss
打印:
(gdb) p *this
$6 = {_vptr.CBoxBoss = 0x55555555db28 <vtable for CBoxBoss+16>, m_vecWorkerThreads = std::vector of length 0, capacity 0,
m_pMasterThread = 0x0, m_CountLock = {<std::__mutex_base> = {_M_mutex = {__data = {__lock = 0, __count = 0, __owner = 0,
__nusers = 0, __kind = 0, __spins = 0, __elision = 0, __list = {__prev = 0x0, __next = 0x0}},
__size = '\000' <repeats 39 times>, __align = 0}}, <No data fields>}, m_dwThreadCount = 0, m_dwCalcThreads = 0,
m_dwSeriesMemberCount = 0, m_pThreadParams = 0x0, m_pSums = 0x0, m_dXtoCalc = 0, m_dResult = 0, m_bQuitRoguish = false,
m_bNeedNotify = false, m_nDoorBells = {0, 0, 0, 0, 0, 0}, m_pChairMan = 0x55555555e148 <chair>}
(gdb) p *this->m_pChairMan
$7 = {m_nNoticeCounter = 0}
一切正常。那就continue,
Thread 35 "slock" hit Hardware watchpoint 1: boss.m_pChairMan
Old value = (ChairMan *) 0x55555555e148 <chair>
New value = (ChairMan *) 0x15555e148
ParallelCalc (pParam=0x55555e609530) at boxboss.cpp:87
87 pParam->pBoss->Notify(nThreadIndex,1);
又一次更改值了
(gdb) l
82 dwWait = 100000;
83 sleep(1);
84
85 if(pParam->pBoss->m_bNeedNotify) {
86 pParam->pBoss->m_nDoorBells[nThreadIndex] = 1;
87 pParam->pBoss->Notify(nThreadIndex,1);
88 }
89 pParam->pBoss->m_CountLock.unlock();
90
91 d4d(_T("Thread %d is done and quitting..."),nThreadIndex);
应该是这条语句把内存指针踩坏了。
(gdb) p *pParam->pBoss
$8 = {_vptr.CBoxBoss = 0x55555555db28 <vtable for CBoxBoss+16>,
m_vecWorkerThreads = std::vector of length 20, capacity 32 = {{_M_id = {_M_thread = 140735981983424}}, {_M_id = {
_M_thread = 140735973590720}}, {_M_id = {_M_thread = 140735965198016}}, {_M_id = {_M_thread = 140735956805312}}, {
_M_id = {_M_thread = 140735743522496}}, {_M_id = {_M_thread = 140735735129792}}, {_M_id = {
_M_thread = 140735726737088}}, {_M_id = {_M_thread = 140735718344384}}, {_M_id = {_M_thread = 140735709951680}}, {
_M_id = {_M_thread = 140735701558976}}, {_M_id = {_M_thread = 140736381040320}}, {_M_id = {
_M_thread = 140735206651584}}, {_M_id = {_M_thread = 140735198258880}}, {_M_id = {_M_thread = 140735189866176}}, {
_M_id = {_M_thread = 140735181473472}}, {_M_id = {_M_thread = 140735173080768}}, {_M_id = {
_M_thread = 140735164688064}}, {_M_id = {_M_thread = 140735156295360}}, {_M_id = {_M_thread = 140735072433856}}, {
_M_id = {_M_thread = 140735064041152}}}, m_pMasterThread = 0x55555d8ede00, m_CountLock = {<std::__mutex_base> = {
_M_mutex = {__data = {__lock = 2, __count = 0, __owner = 32610, __nusers = 1, __kind = 0, __spins = 0, __elision = 0,
__list = {__prev = 0x0, __next = 0x0}},
__size = "\002\000\000\000\000\000\000\000b\177\000\000\001", '\000' <repeats 26 times>,
__align = 2}}, <No data fields>}, m_dwThreadCount = 4, m_dwCalcThreads = 10, m_dwSeriesMemberCount = 10000,
m_pThreadParams = 0x55555e6094b0, m_pSums = 0x55555e1eb390, m_dXtoCalc = 1, m_dResult = 0.69309718305995138,
m_bQuitRoguish = false, m_bNeedNotify = true, m_nDoorBells = {1, 1, 1, 0, 0, 1}, m_pChairMan = 0x15555e148}
数组越界了。
(gdb) p nThreadIndex
$9 = 8
大于6
继续执行就segment fault了:
(gdb) c
Continuing.
Thread 35 "slock" received signal SIGSEGV, Segmentation fault.
0x00005555555598d6 in ChairMan::Notify (this=0x15555e148, worker_id=8, notice=1) at chairman.cpp:9
9 this->m_nNoticeCounter++;
程序没有退出,原因是又signal处理
增加一个断点
(gdb) b calc_signal_handler(int)
Breakpoint 2 at 0x55555555717c: file boxboss.cpp, line 56.
(gdb) c
Continuing.
Thread 35 "slock" hit Breakpoint 2, calc_signal_handler (sig=11) at boxboss.cpp:56
56 d4d("catcha:received signal %d: ", sig);
(gdb) bt
#0 calc_signal_handler (sig=11) at boxboss.cpp:56
#1 0x00007ffff6c7c320 in <signal handler called> () at /lib/x86_64-linux-gnu/libc.so.6
#2 0x00005555555598d6 in ChairMan::Notify (this=0x15555e148, worker_id=8, notice=1) at chairman.cpp:9
#3 0x00005555555570eb in CBoxBoss::Notify (this=0x55555555e0a0 <boss>, thread_id=8, notice=1) at boxboss.cpp:36
#4 0x000055555555735e in ParallelCalc (pParam=0x55555e609530) at boxboss.cpp:87
#5 0x000055555555741d in CalcThreadProc (p=0x55555e609530) at boxboss.cpp:109
#6 0x00005555555597c9 in std::__invoke_impl<unsigned int, unsigned int (*)(void*), _THREADPARAM*>
(__f=@0x55555e6240b0: 0x555555557392 <CalcThreadProc(void*)>) at /usr/include/c++/13/bits/invoke.h:61
#7 0x00005555555596c3 in std::__invoke<unsigned int (*)(void*), _THREADPARAM*>
(__fn=@0x55555e6240b0: 0x555555557392 <CalcThreadProc(void*)>) at /usr/include/c++/13/bits/invoke.h:96
#8 0x0000555555559585 in std::thread::_Invoker<std::tuple<unsigned int (*)(void*), _THREADPARAM*> >::_M_invoke<0ul, 1ul>
(this=0x55555e6240a8) at /usr/include/c++/13/bits/std_thread.h:292
#9 0x00005555555594ee in std::thread::_Invoker<std::tuple<unsigned int (*)(void*), _THREADPARAM*> >::operator()
(this=0x55555e6240a8) at /usr/include/c++/13/bits/std_thread.h:299
#10 0x00005555555594b0 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<unsigned int (*)(void*), _THREADPARAM*> > >::_M_run (this=0x55555e6240a0) at /usr/include/c++/13/bits/std_thread.h:244
#11 0x00007ffff6f62bb4 in ??? () at /lib/x86_64-linux-gnu/libstdc++.so.6
#12 0x00007ffff6cd3a94 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#13 0x00007ffff6d60c3c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
整个异常流程:
(gdb) l
51 return numerator/n;
52 }
53 }
54
55 static void calc_signal_handler(int sig) {
56 d4d("catcha:received signal %d: ", sig);
57 if(sig==SIGSEGV) {
58 d4d("calc_signal_handler: SEGMENT FAULT");
59 longjmp(calc_safe_env,1);
60 } else if(sig==SIGINT) {
(gdb) l CalcThreadProc(void*)
90
91 d4d(_T("Thread %d is done and quitting..."),nThreadIndex);
92 return 0;
93 }
94
95 uint32_t CalcThreadProc(void *p) {
96 uint32_t ret = 0;
97 PTHREADPARAM pParam=(PTHREADPARAM)p;
98 #ifdef GE_USE_C_JMP
99 signal(SIGSEGV, calc_signal_handler);
(gdb)
100 signal(SIGINT, calc_signal_handler);
101
102 int rp = setjmp(calc_safe_env);
103 if(rp!=0) {
104 d4d("bad exception occurred, log and quit");
105 return -1;
106 }
107 #endif
108 try {
109 ParallelCalc(pParam);
(gdb) b 104
Breakpoint 3 at 0x5555555573f6: file boxboss.cpp, line 104.
(gdb) c
Continuing.
Thread 35 "slock" hit Breakpoint 3, CalcThreadProc (p=0x55555e609540) at boxboss.cpp:104
104 d4d("bad exception occurred, log and quit");
(gdb) n
105 return -1;
(gdb)
115 }
(gdb) c
Continuing.
[Thread 0x7fff6ffff6c0 (LWP 32610) exited]
异常退出了,但锁没有释放。
总结:加解锁一定要简介,中间异常出去了,unlock没有被调用。
gtk4改造的代码:
#include <gtk/gtk.h>
#include <malloc.h>
#include <fcntl.h>
#include <stdlib.h>
#include "boxboss.h"
#define GE_FLAG_THREAD_MALLOC 1
#define GE_FLAG_EXIT 2
#define DATA_BUFFER_LENGTH 2
int *g_databuffer = NULL;
GtkTextBuffer *g_clist = NULL;
GtkWidget *g_editno = NULL;
void *g_lastmalloc = NULL;
volatile int g_flags = 0;
static size_t g_block_size = 1000;
static int g_block_no = 10;
volatile int g_threads = 0;
volatile int g_malloc_tasks = 0;
GMutex mutex_list;
int trace_fd = 0;
CBoxBoss boss;
ChairMan chair;
#define GETASK_IDLE 1
#define GETASK_MALLOC 1
#define GETASK_NULLP_EVEN 2
#define GETASK_NULLP_ODD 3
//volatile int g_task = GETASK_IDLE;
static void append_list(char *szMsg) {
GtkTextIter iter;
g_mutex_lock(&mutex_list);
gtk_text_buffer_get_iter_at_offset(g_clist, &iter,0);
gtk_text_buffer_insert(g_clist, &iter,szMsg, -1);
//gtk_text_buffer_insert(g_clist, &iter,"\n", -1);
//gtk_text_buffer_set_text(g_clist,"test",-1);
g_mutex_unlock(&mutex_list);
}
#define MSG_LINE_MAX 1024
#define GE_WA_GTKBUG
void d4d(const char * format,...) {
char msg[MSG_LINE_MAX];
va_list va;
va_start(va,format);
vsprintf(msg,format,va);
append_list(msg);
}
static void btn_start_clicked(GtkWidget *widget, gpointer data) {
g_print("start clicked\n");
boss.StartCalc();
append_list("calculation is started");
}
static void btn_newtask_clicked(GtkWidget *widget,gpointer data) {
g_print("new task clicked\n");
int threads = 10;
boss.NewTask(1, threads, 10000);
d4d("new task is planed with %d workers. pls. click start to kick off.",threads);
}
static void btn_notify_clicked(GtkWidget *widget,gpointer data) {
bool checked = boss.GetNotify();
boss.SetNotify(!checked);
d4d("notify flag is %s",boss.GetNotify()?"set":"cleared");
}
static void activate(GtkApplication *app, gpointer user_data) {
GtkWidget *window;
GtkWidget *vbox = NULL, *hbox;
GtkWidget *scrolled_window,*view;
GtkTextBuffer *buffer;
GtkWidget *btn_start,*btn_newtask;
GtkWidget *btn_notify;
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window),"slock by zxl");
gtk_window_set_default_size(GTK_WINDOW(window), 700,500);
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
//gtk_container_set_border_width(GTK_CONTAINER(hbox),5);
//gtk_container_add(GTK_CONTAINER(window),hbox);
//gtk_widget_show(hbox);
gtk_window_set_child(GTK_WINDOW(window),hbox);
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
//gtk_widget_set_usize(vbox,100,200);
//gtk_box_pack_start(GTK_BOX(hbox),vbox,FALSE,TRUE,0);
gtk_box_append(GTK_BOX(hbox),vbox);
btn_start = gtk_button_new_with_label("Start");
btn_newtask = gtk_button_new_with_label("New Task");
btn_notify = gtk_check_button_new_with_label("Need Notify");
g_signal_connect(btn_start,"clicked",G_CALLBACK(btn_start_clicked), NULL);
g_signal_connect(btn_newtask,"clicked",G_CALLBACK(btn_newtask_clicked), NULL);
g_signal_connect(btn_notify,"toggled",G_CALLBACK(btn_notify_clicked),NULL);
gtk_box_append(GTK_BOX(vbox),btn_start);
gtk_box_append(GTK_BOX(vbox),btn_newtask);
gtk_box_append(GTK_BOX(vbox),btn_notify);
scrolled_window = gtk_scrolled_window_new();
gtk_widget_set_hexpand(scrolled_window,TRUE);
gtk_widget_set_vexpand(scrolled_window,TRUE);
view = gtk_text_view_new();
gtk_text_view_set_editable(GTK_TEXT_VIEW(view),FALSE);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(view),FALSE);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrolled_window),view);
gtk_box_append(GTK_BOX(hbox),scrolled_window);
//buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
//gtk_text_buffer_set_text(buffer, "hello", 5);
g_clist = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
//gtk_text_buffer_set_text(g_clist, "hello",-1);
gtk_window_present(GTK_WINDOW(window));
}
int main(int argc, char **argv) {
GtkApplication *app;
int status;
boss.Setup(&chair);
//g_thread_init(NULL);
g_mutex_init(&mutex_list);
app = gtk_application_new("org.gtk.slock",G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, "activate",G_CALLBACK(activate),NULL);
status = g_application_run(G_APPLICATION(app),argc,argv);
g_object_unref(app);
return status;
}
还有个问题,就是符号无法下载,提示下载超时:https://debuginfod.ubuntu.com, 怎么弄也不行,最后kexue上网解决了,再次骂这个qiang,正常技术网站也屏蔽。
xxx是上网代理,临时设置一下:
export http_proxy="http://xxx:8080/"
export https_proxy="https://xxx:8080/"
再使用gdb就好了。