gtk4+gdb线程观察

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就好了。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值