Python 板


LINE

今天改的版本,突然间陷入 while loop 无法中止 强迫中止时错误讯息是 File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/ threading.py", line 1388, in _shutdown lock.acquire() 这种讯息有和没有差不多 有 lock 没有释放? 於是我写了个 MyLock 取代 threading.Lock 开始记录到底是哪个 Lock 有进入而没有退出 全都有退出!根本查不到 最後是透过 git 不断卷回旧版,找到十二小时前的版本还可以正常退出程式 一查,重点不在程式,在资料! 某一种资料格式,我会启动 Timer, 而 Timer 时间到後,我会再重启 Timer (其实就是连续脉冲波,每隔几秒一次的意思) 因为我预约了下一次的执行需求,所以程式无法释放 只要 cancel timer, 就解掉这个 bug 了 (bug 是一直存在的,只是一直没键入这种资料凸显 bug) 还真是忘了,在 Python 的 Timer 是以 Thread 来实现 而骨子里可能设了个 lock 那我问题来了:这次是幸运在 git 里保存够多细节,且能卷回一定能释放的旧版 假设没这样的环境,只能靠我自己抓,而错误讯息又只说有 lock 没释放 我能回溯知道是哪一行程式产生的 lock 锁住了吗? 有什麽参数,什麽 debug tool 能用吗? 谢谢 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 116.241.233.114 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Python/M.1680299059.A.BEA.html
1F:→ robert09080: Rlock 试试? 04/01 11:21
RLock 是允许重复进入,避免同一个 thread 自己把自己卡住 而我的要求是回应卡住的物件是在哪行指令生成 举例来说 Line 10: a = new C1() # test.c 这是产生物件;目前都有自动释放,但假如在没自动释放的 C 语言 而且我没有释放物件,造成记忆体浪费, 有工具能回应我,浪费的记忆体在 test.c/Line 10 吗? 我还真用过这种工具
2F:→ lycantrope: gdb 04/01 12:27
哇!我试试! 谢谢 ... 超过我的程度 XD 装了,跑不起来.. ※ 编辑: HuangJC (116.241.233.114 台湾), 04/01/2023 15:21:44
3F:推 b0920075: c/c++ 的话有 sanitizer valgrind 之类的工具可以看 04/02 17:33
4F:推 poototo: 有考虑...print吗?cc 04/03 20:03
5F:→ lycantrope: cc 04/03 20:16
6F:→ leolarrel: 我猜二楼其实是要说pdb?? 04/05 17:35
当年我用过 debug tool 抓记忆体漏洞之类,真的过瘾 但有种很怪的感觉,那是高手在替我做事,而且能力是有限的 比如找寻未释放记忆体的原理是什麽? a = new C1() // 配发记忆体 a del a // 释回 a 如果 a 忘记释放,要怎麽找出 a 在哪一行配发的? 毕竟 a 这个符号可能被重覆配发,也可能 b = a // 被 b 承接走 a = NULL // 弃用 a 这个符号,但 b 忘了释放 XD 因此这种 tool 能做的只有。。当初 a 配发时,就把 debug info 顺便存入 比如覆写 new 这功能,成为 DEBUG_NEW 然後隐性的传入程式的资讯(利用 __FILE__, __LINE__ 这种 compiler 维护的符号) 这也代表配发记忆体时,我本来只配几个 byte, 但可能同时配发更多的 debug byte 因此 debug 时的速度会变慢,耗用记忆体会增加 但高手替我抓还是很好用 XD 等我程式写太大时,这种 tool 因为要多耗用很多 debug 资源,就会跑不动 最佳方案仍然是自己写 debug tool 但我如果功力高到会写 debug tool,我当初就不会犯错了! 先有鸡还是先有蛋的问题 -------- 总之我这次学到了,Timer 元件其实要注意它的配发和释放 ※ 编辑: HuangJC (123.204.157.162 台湾), 04/06/2023 01:08:28
7F:推 andy19960407: 为什麽一般感觉不太会遇到这种问题,你的需求是特 04/06 23:27
8F:→ andy19960407: 别刁钻还是你的写法有可以再优化的地方? 04/06 23:27
是遇到了才知道遇到了啊.. 我一开始可超级谨慎的 class MyApp(App): def f1(self): self.destroy() app = MyApp() pApp = weakref.proxy(app) btn = PushButton(app, command=pApp.f1) app.display() 比如我曾这样写程式,其中 pApp 根本没必要 为什麽这样写?因为我怕 btn 物件里如果保有 app 因为参考到自己,会导致永不释放 所以凡参考我都只留 weak 版本 後来我发现不这麽写,照样不会卡,照样释放,想法可以很单纯 XD 我从完全没有 gc 的 C 语言学起的,从前记忆体管理都自己来 那时如果释放了不把变数标成 null, 再叫用到就 null access 能碰到的问题可非常多 a = new C1(); b = a; // 比如进入函式,也是拷走一个 a 指标在函式里用 del b; // 除非我不在函式里释放物件,否则当然会写这种东西 a.xxx // 这时外面还想取用 a pointer 就惨了,null access 後来开始用有 gc 的语言,可是参照次数很重要 如果还有任何指标参照到物件,物件就不会释放 那循环参照怎麽算?还真是测了才知道 一般不会遇到?不是,我一开始学时曾经有遇到,但不知道就写了两年 举例来说,树莓派一开机就跑我的程式,但从没想过要关机 执行完毕直接断电,就算程式无法释放,都断电了是有何差别? 只有刻意去想,我就是要让程式释放,才会测试到这件事 比如我可能要写远端更新,要让程式结束并且重开机 喔,还是有很暴力的写法,比如下个 kill process 指令 在程式未能退出的情况下,由 os 端杀掉 XD 会去注意是洁癖吧.. 总觉得,类似档案没有 close 等循序退出问题,如果没做,很不舒服 别人没遇到吗? 比如我在写 ios 手机时,用的是 obj c 我也下载过别人的函式库用 我看别人防这个也防得很严 一堆 weaf ref 在用 应该说,为什麽 python 在参照到自己的指标留着时还能释放 这才是超乎我预期的 XD 所以 Timer 在几秒後才要启动,而它启动时要用到的指标要不要 weak 版? 程式想退出了,几秒後根本就不存在,若保留指标程式就无法退出 那按键按了要退出程式,按键的程式里保留指标,为什麽可以退出 :P 那也是测了才知道。。 QA 不会做这项测试,都专注在跑程式,而不是退出程式 XD 我也是哪天心血来潮才测到的。 那时曾经呼叫同事写的副程式,用 try-catch 包起来呼叫 甚至是每次呼叫前才 load library (本来可以用静态写的,不必这麽麻烦) 呼叫後就 free library 为什麽要这样做?因为同事记忆体释放没写好啊,我整个 free 掉才会乾净 所以一般是没遇到,还是没注意到? ※ 编辑: HuangJC (123.204.157.162 台湾), 04/07/2023 01:00:44 甚至我想过一个问题:参照到自己,或说交互参照 这种还有法子释放资源是怎麽做的? (同事是说有很多论文,不过我不擅长查) 如果说这机制有 bug 会不会我刚用没问题,但用多了,资源就变无法释放? 那这不是我有问题,是写释放的有 bug, 没确实 implement 出来 看过是说 gc 不会时时刻刻,而是久久做一次 所以我以前去主动检查有没有释放,也常没释放 必需在主动检查前,先主动催 gc 做一次垃圾搜集 会不会就是因为这样,我下载的第三方函式库才广用 weak 版本?
9F:→ Hsins: 这些资讯不够去找,复现的情境也不够清楚,能够复现的话就 04/07 18:10
10F:→ Hsins: 多埋几个点去 logging 吧 04/07 18:10
11F:→ Hsins: 树莓派那段看不是很懂,你叙述了你的做法,但没有叙述为什 04/07 18:12
12F:→ Hsins: 麽要这样做。这也是为什麽前面会说一般不会遇到,他想了解 04/07 18:12
13F:→ Hsins: 的是你的「需求」跟你现在的「问题」之间是不是存在 X-Y 问 04/07 18:12
14F:→ Hsins: 题 04/07 18:12
15F:推 leolarrel: Hsins,建议你可以a他id参考一下 04/07 18:28
a 我 id 其实没帮助 我直说好了,有人说我半桶水 那我能怎样?膨风说自己全都懂? 前不久和另一位也是资深工程师聊这边的状况 聊到有人叫我去读 os,他直接回我,他也从业几十年,但从没读过 os 所以我们只能这麽说:底线就是,这本来就是我的责任 资讯不够,多少是因为我不能把公司产品全丢到网路上,source code 公开 所以得用各种抽象的方式,只曝露一些点来讨论 若实在是不行也就算了
16F:→ Hsins: ~ " ~ 不是很能读懂问题... 04/07 19:42
17F:推 Sunal: 建议问问题可以把完整脉络写出来(包含范例、使用情境、需求 04/08 09:54
18F:→ Sunal: ),而不是大量的类似内心os的口语文字。简单说就是文字要 04/08 09:54
19F:→ Sunal: 精炼一点 04/08 09:54
20F:推 Sunal: 另外,写python其实不需刻意del变数的,用不到gc自然就收 04/08 09:57
21F:→ Sunal: 走了(simple is better) 04/08 09:57
这我知道,知道还这麽做,就代表混入 debug 等心得.. 当年写 c,写到某个地方,我说怀疑 compiler 有 bug 也是被人狠狠嘲笑 几年後看到脸书上另一个朋友说,c compiler 有一大堆 bug... 咦,原来也有别人遇到,那我被笑又怎麽回事;只能说有没有人同样见识到了 责任不能推到 compiler 去,但我们得去验证这些问题存不存在 所以对这些都是有限信任 obj c 也是有 gc 的 (应该说随着年代, 很多语言的特性互相学习) 而它若是自我参照时,就不会释放! 这我能写一个极小的程式验证到 发生时,就要'打破这个环节' 在 obj c 我也不会去 del, 我是把指标设为 None 这样循环参照就打破了 (我这篇里用到 del, 但那是 c 啊,先还原到最原始,没有 gc 的环境描述问题) 去说明这些我知道似乎也没有意义 知道我也是碰到这些 bug 了
22F:推 andy19960407: Sunal懂我 哈哈哈 04/08 11:10
23F:推 Sunal: threading.py", line 1388, in _shutdown 04/08 11:50
24F:→ Sunal: 光这一行就可以从 python threading.py source code 知道 04/08 11:50
25F:→ Sunal: class Timer(Thread): 这件事情...(而且文件也有写) 04/08 11:51
Timer 是一种 Thread 这我知道 我不知道的是我启动了 lock lock 一般来说,是 multi-thread 时, 某 thread 要求独占资源,其它 thread 不能进入 而我使用 Timer 时,我没要独占什麽,所以我没想到它启动了 lock 或者,这问题不是 Timer 启动了 lock 我程式中本来就用了很多 lock, 凭最後出现的错误讯息,我并不知是哪个 lock 未释放 不然改个说法:我能不能把每个 lock 命名 当程式用强迫退出的方式并且收到错误讯息 能够知道是哪个 lock 没有释放 ※ 编辑: HuangJC (116.241.233.114 台湾), 04/08/2023 16:24:15
26F:推 Sunal: source code 中也有用到 lock 如果你看到错有去看 code 就 04/08 16:42
27F:→ Sunal: 知道了 04/08 16:42
28F:→ Sunal: 另外,你也可以debug时hack python source 去达到你的目的 04/08 16:44
蛮常 hack 的,但还是不行,主要是猜测行为都猜错了,就无法看着 code 想像 来看这麽短的程式就好 from guizero import App, PushButton app = App() btn = PushButton(app, command=app.destroy) app.display() 这程式的目的只有一个:产生一个按键,按了就退出程式 我本来以为这不会正常运作的 理由是 btn 是个物件,它里面有变数参照了 app.destroy 那这样 app 的 ref count 不是会加一吗? 不用执行,光有变数拷走我的指标,就要加一了,没错吧.. 不然万一要执行时 app 不存在怎麽办? 按下按键,我以为程式要卡死不能退出,但它就是顺利退出了 我就是以为,这个 gc 可以自行解决啊? 结果 timer 的倒没自行解决,得由我来 cancel timer! ※ 编辑: HuangJC (116.241.233.114 台湾), 04/09/2023 13:21:02
29F:推 Sunal: 感觉你还是没搞懂,实在帮不了。包含我前面说的「建议」也. 04/09 13:50
30F:→ lycantrope: 很难救 04/09 14:51
31F:→ Hsins: 既然都在处理 thread 跟 lock 问题,去把 OS 里这部分的概 04/09 15:54
32F:→ Hsins: 念补齐满合理的…… 04/09 15:54
要讲这麽笼统的话,建议计概重学,建议 python 重学,不也都说得通? 成语 邯郸学步 就这意思了 学着学着有没有更高明?还是反而被搞糊涂了呢? thread 就我所知,就是系统把目前所有的暂存器通通储存起来, 然後切换到另一个 thread 的 context 去 之後再切换回来,除了时间点改变之外,CPU 完全可以在这个点继续往下执行 而两个 thread 如果有共用变数,且抢着修改,可能混成一团 因此在有必要独占一个变数时,就可以用一个同步物件来 lock 使用权 当然随着应用的方式不同,看起来也许不像锁着物件,而像锁着程式区块 比如 critical section 的应用方式 知道,但解决不了 因为在这个地方忽略而产生 bug, 错讯讯息不见得是在这个地方 所以我是在请教 debug 技巧 就以我文章最前面所讲的问题,我是已经解决了 我是知道解法,再回头看错误讯息,觉得没有帮助 其实我想要的是在程式强硬退出後,有'列举所有 thread 状态'这类指令 所以我已经在打造自己的 debug tool 了 希望可以追踪 thread 当下的行为,以知道 thread 为何释放不了 ※ 编辑: HuangJC (49.217.174.143 台湾), 04/10/2023 01:51:25
33F:→ leolarrel: 就跟你们说那边有马蜂窝了,你们... 04/10 11:31
淌浑水都是自愿的,而且都不是简单的工程 你说马蜂窝又怎样呢?
34F:→ s9041200: 楼上+1 04/10 21:25
35F:→ s9041200: 如果可以稳定重现又有行数其实蛮幸福的,对准点直接打lo 04/10 21:25
36F:→ s9041200: g就好。 04/10 21:25
37F:→ s9041200: 之前写mit 6.824有deadlock都是这样找的。 04/10 21:25
38F:→ Hsins: 我觉得这篇叙述的思考方向很怪……对我来说,应该是试图找 04/10 22:00
39F:→ Hsins: 到问题点,而不是去找一个或者是造出一个专门的除错工具… 04/10 22:01
在针对微软出的一本比一般砖块还大的经典书籍,教人 debug 时 就有介绍到自己打造 debug 工具 差别是时代进步後,会有人直接准备好这个工具给你
40F:→ Hsins: 能够复现当然是最好,不能够复现会去找相关日志,如果日志 04/10 22:02
41F:→ Hsins: 不足以判断,那说明日志输出的埋设点不足;以你的例子来说 04/10 22:02
42F:→ Hsins: ,我不会想着要怎麽在强制退出後列出 thread 状态这件事, 04/10 22:03
43F:→ Hsins: 而是纪录 thread 切换不同状态,以及他的初始化和结束。 04/10 22:05
埋设本身就是一堆 code,如果这种 code 重覆用,就值得打造一个工具 所以你其实不能反驳我的做法 最单纯的 log, 类似 echo abc >> myApp.log 但复杂的也是 import logging,有人打造好了不是? 以分配记忆体的 new 指令来说 a = new C1(); 改成 a= DEBUG_NEW c1(); 这样的思维逻辑,不是我想出来的,是经典书籍上有的 你可以说现在时代进步,这招太旧 但这招真的不是我想的。
44F:→ Hsins: 另外,你是不是曲解邯郸学步的意思了?建议回去补足作业系 04/10 22:07
45F:→ Hsins: 统知识,我认为有其必要性;至於学习的好不好,那是学习者 04/10 22:09
46F:→ Hsins: 策略跟方向上可能有错误,不代表这个建议是错误的呀。  04/10 22:10
那我也只能说谢谢了 不管你说要学多少东西,谦虚的人绝不会说那是错的 作业系统我不会不懂,但要说哪一块挂万漏一恰好不熟,当然有可能 如果我比你高明,我说你作业系统不熟该重学 想必你也不会拒绝 问题在能不能点出章节,不然是不是要投入好几个月甚至几年?
47F:→ Hsins: 我反倒觉得如果有资深工程师说从业十几年,没读过作业系统 04/10 22:11
48F:→ Hsins: ;而有人听信去效法,却落得基础不扎实,资深只与从业时间 04/10 22:12
49F:→ Hsins: 长短而无关能力,那才真的是在邯郸学步… 04/10 22:12
50F:推 Hsins: 不过我很支持你打造自己的除错工具,但如果你有时间压力, 04/10 22:28
51F:→ Hsins: 多埋一些日志会比较适合 04/10 22:28
这是同一回事,我的除错工具,主要工作就是在埋日志
52F:嘘 s860134: 又是不读完文件搞自干 04/16 12:48
53F:→ s860134: python 都能step by step debugging 你还在插扣 04/16 12:49
步进执行我有用喔.. 有用我还是解不了这个问题
54F:推 wuyiulin: pdb 04/16 15:32
55F:→ wuyiulin: 会推 pdb 是因为可以同时查多个变数 比 step by step 04/16 15:33
56F:→ wuyiulin: 还有效率 04/16 15:33
57F:→ wuyiulin: 然後也推看到什麽学什麽,目测要重看OS是对的xD 04/16 15:35
我不是说了嘛,我是 bug 已经解了,回头看错误讯息,觉得错误讯息没帮助 我可以把程式写个很精简的小范例重现 bug 但我还是不懂那和 OS 的关系在哪 何谓 thread? 那我乾脆就默了一段出来 以此代表在 OS 我也是了解这段的(而其他段或许不了解) 既然要说我对 OS 了解不够 那是不是也默一段出来,说说我哪里错了?
58F:嘘 s860134: 笑死 还查多个变数 又是不会用 debugging 的在搞笑 04/23 17:25
59F:→ s860134: https://bit.ly/2kVHaP7 04/23 17:27
60F:→ s860134: 如果你只会 pdb 还是乖乖插code 好吗? 中断点有用过? 04/23 17:28
61F:→ s860134: 如果这些都不会 还是回去写 C++, python 的功能对你鸡肋 04/23 17:29
62F:→ wuyiulin: 原来叫只会 pdb,阁下开发的时候都有IDE辅助 484写网页 04/23 19:22
63F:→ wuyiulin: 的 484? 04/23 19:22
64F:→ wuyiulin: 如果你是讲 breakpoint() 那东西我印象等效 pdb 04/23 19:24
65F:→ wuyiulin: 但是我目前 maintain 的专案版本没有 breakpoint() 可 04/23 19:25
66F:→ wuyiulin: 以用 所以也没用过 就不妄评 04/23 19:25
67F:→ wuyiulin: VSCode 的中断点的话(灿笑) 04/23 19:25
68F:嘘 s860134: ㄜ..... 没用过就没用过,pdb 跟你插扣没两样 04/23 19:46
69F:→ s860134: 我还建议你用 IPython.embed() 至少还有自动补完 04/23 19:47
70F:→ s860134: 真的是不懂装懂的一个样,还以为你会说出用 GBD attach 04/23 19:47
71F:→ s860134: 也是拉 反正都嘛看看 built in 和 for loop 怎麽写就上工 04/23 19:50
72F:→ s860134: 能写 if else for loop 就算会 python 了 04/23 19:50
73F:→ s860134: https://wiki.python.org/moin/DebuggingWithGdb 04/23 19:55
74F:→ s860134: 怎麽 debugging cpython 自己跑一次看看吧 号称写C十几年 04/23 19:56
75F:→ s860134: 的应该会用? gdb? 04/23 19:56
不见得会 C 再熟,看别人程式也会需要重新熟悉 又不是别人程式用 C 写的,而我写 C 久了,我就一定能看懂 如果你是一定能看懂别人程式,其实你很优秀 :P 老实说我很久没碰 C 了,但对 C 的语法一直是还在参考 因为一堆语言是 c like 啊,C 应该算我的基础 gc, 垃圾搜集,c 没有吗? (啊,还真难一点,改说 c++ 好了) 在建构,解构式里,埋 reference count 这些 其实也是慢慢发展出来的 更别说同样是 c, 换了一套 ide, 结果环境不熟 但基本就是一样,step, trace into.. 所以从 python 的直译器去,会很快见到问题? 这想法有点怪,有点在 python 解不了,去找外挂的感觉 就好像 c 看程式解不了,去找执行档反组译成组合语言解的感觉 然後如果我说我组合语言写十几年 你回呛说那当然可以直接看组合语言 啊。。组合语言是懂,但可读性是那样子 不在高阶语言的高度直接解,不嫌辛苦? 我承认有个时候会需要进组合语言解: 怀疑 c compiler 本身有 bug,要看它做错什麽时 但如果信任 c compiler, 这事我就不干了...
76F:→ wuyiulin: 我在跟你讨论中断点还有 pdb,这样也可以拉 gdb 救援? 04/23 20:03
77F:→ wuyiulin: g维拉 04/23 20:03
78F:→ s860134: 我在跟你说怎麽 debugging ,你啥都不会 pdb? 04/23 20:04
79F:→ s860134: 拜托 当你要加一行 pdb 进 code 里就 lowwwww 掉了 04/23 20:04
80F:→ s860134: 更何况 pdb 提供的功能如此原始,你这样效率怎麽上工? 04/23 20:05
81F:→ wuyiulin: 还好我上工的时候早就熟悉其他更 efficient 替代 for l 04/23 20:05
82F:→ wuyiulin: oop 的方式,感谢你这麽关心别人的职涯欸。 04/23 20:05
83F:→ s860134: 就是说你的方法没效率 土炮 没看文件 就这样 04/23 20:06
※ 编辑: HuangJC (123.204.157.211 台湾), 05/04/2023 03:40:36
84F:嘘 s860134: 又是再讲废话... 05/06 17:05
85F:→ s860134: 我贴的每一个方法都能直接显示中断的python code位址和当 05/06 17:07
86F:→ s860134: 前变数值,即使多线程也能 不要没用就先用你那狭隘的见解 05/06 17:07
87F:→ s860134: 去评断 05/06 17:07
88F:→ s860134: 只是满嘴专有名词呼拢人的小白罢了 05/06 17:08
89F:→ s860134: 我不关心你写几年 我只知道你学习能力很差而已 05/06 17:08
我学习能力差一样不用你关心啊 我是什麽重要的人影响到你了吗? 难道我说你学习能力很好,你能接受? 你没这麽自大吧。。。 对我来说,我的重点只有'这个我不会' 其他不重要,也没那麽自大 我相信我有多谦虚,你也有 ※ 编辑: HuangJC (123.241.134.39 台湾), 12/01/2023 21:09:11







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP