Forwarded from Welcome to the Black Parade
我们来讨论一下伊洪大哥最近在查的 cpython bug https://github.com/python/cpython/issues/135329
TLDR 不要看里面 j 某人的回复,是错的😀
我们从头开始。
strace ./python 然后 ctrl-c 发现 python 进程无限报错循环。 strace 很复杂,先想办法剥离关键因素,试试单独跑 ./python 然后 strace -fTp $(pidof python) 再 ctrl-c,嘿不报错!太好了说明不是 ptrace 引发的错误,而是进程管理、终端、信号相关的问题。太好了,不然我又要去看一遍 signal-delivery-stop...
那就手动来一层套娃。已知 shell -> strace -> python repl 的进程树有问题,但是 strace ptrace 又并非关键,那就把 strace 换掉试试看: shell -> python -> python repl:
再 ctrl-c,居然也可以复现!
那就好办了,strace -fTttp $(pidof python) &>crash.strace.log 启动!
ioctl 返回 EIO 循环了。
继续剥离,用 strace 注入 syscall error:
此时的 python 进程不需要套娃,shell 直起也能 ctrl-c 报错。
所以可以确定 cpython bug 了:cpython 无法正确 EIO 报错,一旦 EIO 就触发 cpython 做栈回溯 + ioctl,进而触发新一轮的 EIO,无限循环。注意这是 python 3.13 new repl 的功能,所以也解释了为什么旧版 cpython repl 不会陷入此报错循环。
以上你并不需要知道 OS 的细节就可以追查到,希望大家都可以反复练习熟练掌握。
下面进入内核,为什么内核返回 EIO?因为伊洪要写测试,所以在容器内正确地创造出 EIO 还是很重要的。
retsnoop 抓一波
去看内核 __tty_check_change 的源码,里面只有两处 return -EIO
所以是进程收到 SIGTTOU 时候,如果 TTOU 没有被 ignore,而进程所在的进程组是孤儿(注意:孤儿进程组 != 孤儿进程),则返回 EIO。
SIGTTOU 的触发条件是后台进程写控制终端,所以这里要求的进程结构至少应该是 p1 (1号进程,创建 session 和 pty) -> p2 (repl), p1 设置自己为前台进程组,设置 p2 repl 为后台进程组,此时 repl IO 触发 TTOU。
孤儿进程组要麻烦一点,我们先考虑最简单的三层进程树: p1 (1号进程,创建 session pty) -> p2 (独立进程组,exit immediately) -> p3 (repl),由于 p2 退出,p3 孤儿被 re-parent 到 pid 1 即 p1,此时由于 p1, p3 依然在一个 session,p3 并非处在孤儿进程组。
因此要考虑一个复杂的四层进程树: p1 (1号,不做事) -> p2 (创建 session pty) -> p3 (独立进程组,exit) -> p4 (repl)。此时 p4 会被 reparent 到 p1 ,所以 p4 所在进程组的全部进程(只有 p3 p4 但 p3 无了)的父进程们都和进程组的父进程们不在同一个 session,满足了孤儿进程组。
TLDR 不要看里面 j 某人的回复,是错的
我们从头开始。
strace ./python 然后 ctrl-c 发现 python 进程无限报错循环。 strace 很复杂,先想办法剥离关键因素,试试单独跑 ./python 然后 strace -fTp $(pidof python) 再 ctrl-c,嘿不报错!太好了说明不是 ptrace 引发的错误,而是进程管理、终端、信号相关的问题。太好了,不然我又要去看一遍 signal-delivery-stop...
那就手动来一层套娃。已知 shell -> strace -> python repl 的进程树有问题,但是 strace ptrace 又并非关键,那就把 strace 换掉试试看: shell -> python -> python repl:
pid = os.fork()
if pid == 0:
exe = sys.executable
os.execlp(exe, os.path.basename(exe))
os._exit(127)
os.waitpid(pid, 0)
再 ctrl-c,居然也可以复现!
那就好办了,strace -fTttp $(pidof python) &>crash.strace.log 启动!
20:18:26 --- SIGINT {si_signo=SIGINT, si_code=SI_USER, si_pid=4678, si_uid=1000} ---
20:18:26 rt_sigreturn({mask=[]}) = -1 EINTR (Interrupted system call) <0.000007>
20:18:26 write(4, "\33[?2004l", 8) = 8 <0.000013>
20:18:26 write(4, "\33[?1l\33>", 7) = 7 <0.000012>
20:18:26 ioctl(3, TCGETS, {c_iflag=IXON|IUTF8, c_oflag=NL0|CR0|TAB0|BS0|VT0|FF0|OPOST|ONLCR, c_cflag=B38400|CS8|CREAD, c_lflag=ISIG|ECHOE|ECHOK|IEXTEN|ECHOCTL|ECHOKE, ...}) = 0 <0.000008>
20:18:26 ioctl(3, TCGETS, {c_iflag=IXON|IUTF8, c_oflag=NL0|CR0|TAB0|BS0|VT0|FF0|OPOST|ONLCR, c_cflag=B38400|CS8|CREAD, c_lflag=ISIG|ECHOE|ECHOK|IEXTEN|ECHOCTL|ECHOKE, ...}) = 0 <0.000006>
20:18:26 ioctl(3, TCSETSW, {c_iflag=ICRNL|IXON|IUTF8, c_oflag=NL0|CR0|TAB0|BS0|VT0|FF0|OPOST|ONLCR, c_cflag=B38400|CS8|CREAD, c_lflag=ISIG|ICANON|ECHO|ECHOE|ECHOK|IEXTEN|ECHOCTL|ECHOKE, ...}) = -1 EIO (Input/output error) <0.000007>
...
20:18:26 ioctl(3, TCSETSW, {c_iflag=BRKINT|IUTF8, c_oflag=NL0|CR0|TAB0|BS0|VT0|FF0|ONLCR, c_cflag=B38400|CS8|CREAD, c_lflag=ISIG|ECHOE|ECHOK|ECHOCTL|ECHOKE, ...}) = -1 EIO (Input/output error) <0.000008>
...
20:18:26 ioctl(3, TCSETSW, {c_iflag=BRKINT|IUTF8, c_oflag=NL0|CR0|TAB0|BS0|VT0|FF0|ONLCR, c_cflag=B38400|CS8|CREAD, c_lflag=ISIG|ECHOE|ECHOK|ECHOCTL|ECHOKE, ...}) = -1 EIO (Input/output error) <0.000008>ioctl 返回 EIO 循环了。
继续剥离,用 strace 注入 syscall error:
sudo strace -e inject=ioctl:error=5 -p $(pidof python)
此时的 python 进程不需要套娃,shell 直起也能 ctrl-c 报错。
所以可以确定 cpython bug 了:cpython 无法正确 EIO 报错,一旦 EIO 就触发 cpython 做栈回溯 + ioctl,进而触发新一轮的 EIO,无限循环。注意这是 python 3.13 new repl 的功能,所以也解释了为什么旧版 cpython repl 不会陷入此报错循环。
以上你并不需要知道 OS 的细节就可以追查到,希望大家都可以反复练习熟练掌握。
下面进入内核,为什么内核返回 EIO?因为伊洪要写测试,所以在容器内正确地创造出 EIO 还是很重要的。
retsnoop 抓一波
# sudo ./retsnoop -x EIO -a '*tty*' -e '*tty*'
10:10:44.178847 -> 10:10:44.178850 TID/PID 30657/30657 (python/python):
entry_SYSCALL_64_after_hwframe+0x76
do_syscall_64+0x7e
x64_sys_call+0x131e
__x64_sys_ioctl+0xa4
2us [-EIO] tty_ioctl+0x515
⌇ 1us [-EIO] n_tty_ioctl+0x85
⌇ 1us [-EIO] n_tty_ioctl_helper+0x2d
⌇ 0us [-EIO] tty_mode_ioctl+0x1c1
set_termios+0x5d
⌇ 0us [-EIO] tty_check_change+0x13
!⌇ 0us [-EIO] __tty_check_change
去看内核 __tty_check_change 的源码,里面只有两处 return -EIO
int tty_check_change(struct tty_struct *tty)
{
return __tty_check_change(tty, SIGTTOU);
}
int __tty_check_change(struct tty_struct *tty, int sig)
{
if (tty_pgrp && pgrp != tty_pgrp) {
if (is_ignored(sig)) {
if (sig == SIGTTIN)
ret = -EIO;
} else if (is_current_pgrp_orphaned())
ret = -EIO;
所以是进程收到 SIGTTOU 时候,如果 TTOU 没有被 ignore,而进程所在的进程组是孤儿(注意:孤儿进程组 != 孤儿进程),则返回 EIO。
SIGTTOU 的触发条件是后台进程写控制终端,所以这里要求的进程结构至少应该是 p1 (1号进程,创建 session 和 pty) -> p2 (repl), p1 设置自己为前台进程组,设置 p2 repl 为后台进程组,此时 repl IO 触发 TTOU。
孤儿进程组要麻烦一点,我们先考虑最简单的三层进程树: p1 (1号进程,创建 session pty) -> p2 (独立进程组,exit immediately) -> p3 (repl),由于 p2 退出,p3 孤儿被 re-parent 到 pid 1 即 p1,此时由于 p1, p3 依然在一个 session,p3 并非处在孤儿进程组。
因此要考虑一个复杂的四层进程树: p1 (1号,不做事) -> p2 (创建 session pty) -> p3 (独立进程组,exit) -> p4 (repl)。此时 p4 会被 reparent 到 p1 ,所以 p4 所在进程组的全部进程(只有 p3 p4 但 p3 无了)的父进程们都和进程组的父进程们不在同一个 session,满足了孤儿进程组。
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Forwarded from Welcome to the Black Parade
上面的结构完美符合我们最初的场景: p1 是操作系统的 1 号进程 init,p2 是 bash shell,p3 是 strace(ctrl-c 之后进程死掉),p4 是 python repl。这个结构恐怕很难简化,如果有哪位老师发现 3 进程可以复现请教教我😇
运行 docker run --name repl -td -v $(pwd):/src python:3.14.0rc2 python /src/main.py,观察到下面的进程树。
strace -p 最新的 python 进程,确认无限 EIO,QED
#!/usr/bin/env python3
import os, sys, pty, fcntl, termios, signal, time
def handler(sig, f):
pass
def spawn_p2():
master_fd, slave_fd = pty.openpty()
os.setsid()
fcntl.ioctl(slave_fd, termios.TIOCSCTTY, 0)
p2_pgid = os.getpgrp()
pid3 = os.fork()
if pid3 == 0:
os.setpgid(0, 0)
os.dup2(slave_fd, 0)
os.dup2(slave_fd, 1)
os.dup2(slave_fd, 2)
if slave_fd > 2:
os.close(slave_fd)
pid4 = os.fork()
if pid4 == 0:
signal.signal(signal.SIGTTOU, handler)
exe = 'python'
os.execlp(exe, os.path.basename(exe))
else:
os.tcsetpgrp(0, p2_pgid)
os._exit(0)
try:
os.setpgid(pid3, pid3)
except ProcessLookupError:
pass
os.tcsetpgrp(slave_fd, pid3)
if slave_fd > 2:
os.close(slave_fd)
os.waitpid(pid3, 0)
time.sleep(1)
os.tcsetpgrp(master_fd, p2_pgid)
while 1:
os.read(master_fd, 1024)
def main():
pid2 = os.fork()
if pid2 == 0:
spawn_p2()
else:
time.sleep(1 << 30)
if __name__ == "__main__":
main()
运行 docker run --name repl -td -v $(pwd):/src python:3.14.0rc2 python /src/main.py,观察到下面的进程树。
root 67924 67901 1 13:49 pts/0 00:00:00 \_ python /src/orp_repl2.py
root 67977 67924 1 13:49 pts/1 00:00:00 \_ python /src/orp_repl2.py
root 67979 67924 79 13:49 pts/1 00:00:02 \_ python
strace -p 最新的 python 进程,确认无限 EIO,QED
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
Running python REPL under another program + Ctrl-C results in an exception traceback · Issue #135329 · python/cpython
Bug report Bug description: Running python REPL under another program (strace ./build/python in my case), then pressing Ctrl-C on Linux results in an infinite stream of exception tracebacks. Tested...
Forwarded from Arcadia
https://github.com/langgenius/dify/pull/24586
上周我在仓库里加了个 CLAUDE.md。说实话,当时还犹豫了一下:Claude Code 的确是现在最火的工具,但名字叫 CLAUDE.md 就没 AGENT.md 那么中立,对用别的工具的人也不算友好。
后来我心想:“反正大不了给它整一个软链接嘛。”
结果今天一看仓库,嘿!
上周我在仓库里加了个 CLAUDE.md。说实话,当时还犹豫了一下:Claude Code 的确是现在最火的工具,但名字叫 CLAUDE.md 就没 AGENT.md 那么中立,对用别的工具的人也不算友好。
后来我心想:“反正大不了给它整一个软链接嘛。”
结果今天一看仓库,嘿!
GitHub
Feat: add AGENTS.md with symlink for Coding Agents by fdb02983rhy · Pull Request #24586 · langgenius/dify
ImportantClose #24585
Related #23946
Summary
https://agents.md/
Screenshots
Before
After
...
...
Checklist
This change requires a documentation update, included: Dify Document
I under...
Related #23946
Summary
https://agents.md/
Screenshots
Before
After
...
...
Checklist
This change requires a documentation update, included: Dify Document
I under...
👍4
高度使用 agent 写代码就能体会到了,有时候自己手动写一行到几行代码,能让 vibe 的效率提高好几倍。大哥们为啥一直宣传一行代码不写,给自己找罪受啊。。。
🤣10👍4
Forwarded from Newlearnerの自留地 ( 初学者 | Newlearner365)
#Channel #Blog #telegram
🎈 写(创)作的心情——写在 Newlearnerの自留地成立六周年
除了第一年的短篇外,每年我都会在频道 8 月 12 日周年庆之前,写作一篇长文,聊聊这一年频道的情况和自己的感想。今年的情况比较特殊,出差完回来遇上亲人离世,没有了写作的心情,所以一直没有动笔
我对夏天的定义,通常是从可以穿短袖开始,到 8 月底结束。不仅仅是因为「处暑」了,而是学生开学、家长忙碌,天气逐渐转凉,失去了享受夏日的心情。所以我想着,在自己心中的夏天结束之前,还是为这个节点写点什么
✈️ 简单介绍一下情况
六周年,离七年之痒还剩一年,Telegram 和这个频道已疲态尽显,不过有时候慢下来并不是一件坏事
• 一年的订阅数增长可以忽略不计,频道和群组充斥着广告 Bot,大家加速逃离平台,新用户进入门槛不断提高,活人感降低
• 数码行业趋向稳定和瓶颈期,圈子已经形成且较为固定,难以流动。大多数人需求是看看实时新闻,不愿也没有时间进行进一步交流
• 频道许多板块停止更新,如「每日一摄」「每周觅食」「游戏周报」;其他周刊变动也较为频繁;往期新年活动以及周年庆征文均未达到预期效果,暂停举办
• 投稿和有意愿创作的人数越来越少,newsletters、播客、博客停更成风。从学生到社会人的身份转变,以及目前的社会形式,使得很多人压力很大、空余时间很少
• 新建了 2 个私密群组,一个聊「泛文娱」相关内容,另一个聊「游戏」相关内容,大家相处较为融洽。遗憾在于说了一年的电影、音乐分享期刊还没有做
• 频道逐渐「小而美」,由固定的几个人负责更新,大家安静地看
看上去坏消息多一些,不过这也是必然的结果。现在 AI 生成内容非常方便,文字、视频内容都卷出了新高度,选择太多就会导致走马观花。坚持创作的好处是,你能在感兴趣的领域不断深耕,不至于落入快节奏的陷阱
主编 Glaze 之前向我展示用 AI 生成的推送,似乎我们只需要负责选择题材,推送就能够自动生成。我和他讲,写作还是要「有人味」,有自己真实的想法。AI 比较适合用于客观事实的总结归纳和推理,但我们写作一定不是搬运这些东西,而是要有自己的观点
从「重启感性」开始,我就逐渐对于产品参数、对比祛魅,不再想过一种「客观理性」的人生。到了「顺流而下」,除了维持频道正常更新外,我主要在流媒体周报和周末总结中用一些文字表达自己近期的所思所想。大多数时间用来探索自己内心的精神世界,以及走出门外
-
新的一年,因为频道会员助力人数不够,我们停止了「每日一摄」的更新。这段时间里,自己精选了超过 5000 张日常照片存入 iCloud,也接触了各种品牌的数码相机、看了许多摄影展,最近还染上了胶片相机(机龄几乎和我一样大)。这是正确的创作的心情,即不是为了创作而创作,而是把创作当成了一种日常;阶段性地满溢,于是和大家分享
后来发现 Telegram 取消了对于频道 Level 2 的要求,无论是否助力都可以每天免费发送一张图片了。昨天试了一下,果然可行,但是被破坏的整个生态,以及失去的与投稿者之间的联系,就很难去修复和挽回了
后来随着足迹遍布许多城市乡村,我终于意识到「每周觅食」存在底层逻辑上的问题:分享者几乎被固定在某个城市(往往是一线),而我们的读者来自五湖四海,觅食推荐十分出彩却往往不具备参考性。这样的分享更应该发生在身边朋友之间,发生在经常拜访所在城市的网友之间。当年这个想法由我提出来,Sol 给予了高水平的开篇,如今我选择终结这个栏目,也谢谢所有参与分享的主编
或许是这几年看过了太多东西,逐渐对探店、出片这种小红书常见的生活方式祛魅,而是想自己创作点什么东西。朋友邀请我下个月去参观他的新家,包豪斯风格,我的第一想法是:或许以后可以以某个朋友的客厅餐桌作为基地,半个月或一个月相聚一次,大家自己带食材做饭、吃饭,聊聊近期感兴趣的话题,一起在客厅打打《马里奥派对》,然后留下一些文字和照片
-
说到疫情很多人都深恶痛绝,但正是因为大家居家无所事事,才开始关注并满足自己的精神需求。这期间自然而然就引发了对于线上社交的渴望,所以当年 Telegram、Clubhouse 都取得了不错的发展,自留地也借这股东风迎来了很多读者
但近几年大家的热情迅速消退了,就像这几年人们不会再谈论 Clubhouse 一样。一方面数码科技产品的发展,和频道的更新一样,几乎成为了一种定期要做的事,并且没有人能够一直高质量地生产新东西;另一方面,经济下行带来的工作压力使得很多人放弃了大部分爱好,也不再愿意在网络上表达自己或是与他人交流;此外,出门看世界成为了网络世界的最佳代餐,与其谈天说地不如说走就走
不过,最让我遗憾的就是,受限于 Telegram 注册门槛、封禁机制以及群聊活跃人群整体年龄段的影响,似乎很少有新高中生、大学生加入群聊和大家交流。老人不断离去,新的活水没有流入,河流就会逐渐干枯
乐观一点来看,目前几个水塘(群聊)都有它们各自的生态位和活跃者。创立频道起初是为了消除信息差,将自己看到的有价值的信息分享出来;后面逐渐更加关注个人成长、自我实现和精神世界,也是为了交友与人聊天;从来没有考虑过赢利,甚至自己贴了不少钱做活动。即便未来频道不更新了,依然能够找得到有趣的人聊天,目标其实已经达成
总之,目前你看到的一切都是经过取舍之后的结果,我的精力毕竟有限,也有自己的生活要过。骨子里,我还是喜欢分享、喜欢写作、喜欢折腾点新东西的。但这些将以一种怎样的质量和形式呈现在大家的面前,和写(创)作的「心情」息息相关
🧑🏻💻 写(创)作的心情
过去的许多年,我一直是一个情绪比较稳定的人,像一台机器一样高效运转。今年开始,不知道是不是因为时间变多、思考的问题变多,心情也开始变得多样,有好有坏。我常常和 理想之地 群友分享自己当下的心情,方式是用一首歌来代表
心情好的时候,譬如听到了还潮乐队那样的现场,亦或是在酒吧遇到了聊得来的店员,我就会进入「心流」。文思泉涌,金句频出,观点一个接着一个。无论是写作、摄影,跟着第一感觉走都能有不错的收获。心情好的时候,我更愿意输出,更愿意与他人建立连接
心情不好的时候,譬如过去的这一个多月,输出就不再定期运转了,我更喜欢停止输出、去寻找输入。正如去年「顺流而下」说的,不再要求按时按点地填满每一个档期,就像我现在不再强迫自己连续合上 Apple Watch 运动圆环一样。心情不好的时候,给自己放个假,出门看世界、与人倾诉,从音乐、电影中汲取养分
-
我最早的创作是从写作开始的,一开始在贴吧发帖分享,后面建立了自己的博客,再到自留地更新的这 6 年多,写作的字数应该远超百万。从一开始搬运新闻,分享一些客观的解决方案,到后来自己的表达愈发多样,不再局限于客观事实,喜欢讲讲故事、聊聊看法
后面发现文字是根基,但也是基础的表现形式。所以我开始用相机记录眼前所见,玩唱片机和吉他表达声音,开汽车带自己拜访异乡的风景和人群,最后再用文字记录下这一切。这样的模式玩得久了,终于意识到,作为一个消费者,对我来讲是远远不够的
去年冬天朋友们带菜来我家小聚,觥筹交错之间聊起了另一个朋友想要做自己空间(小店)的事情。我对此表示不理解,我说人生可以不断体验,你去上海会有最 TOP 的店可以感受。也即我们可以任意拜访有品位格调的地点,为什么要自己做一个更差的。朋友们年龄都比我大,大家安慰我说可能还要玩上几年,才能体会到这一点。他们说,消费总有尽头
用不了几年时间,今年我就意识到,消费者和创作者是两种不同的境界,获得的乐趣也相差甚远。我们自己办电影放映、唱片分享、DJ Remix、插电活动,做实体唱片墙、布置隔音和声学空间、采购舒适的座椅、设计调酒和灯光,真正把大家多年来的美学欣赏和个人品味,转化为了实体的东西。许多浅尝辄止的东西,当你开始想要表达,就必须垂直深挖,创作表达的同时也在不断学习。想做的东西还有很多,一场个人摄影展、一份音乐小报,甚至是一个分享做菜和喝酒的小客厅
这就好比「野鱼志」里面的一个个业余项目,受众不多但是有趣,就像自己的孩子一样。以石击水,能激起层层涟漪,只要开始创作和表达,会有越来越多有趣的人和事走到你面前。这是我去消费、去索取很难获得到的 —— 在他们眼中,我是那个有趣的过客,而我能获得什么只能由他们来主导。今年开始,我和朋友们决定夺回主动权,正如当年创立自留地的心情那样
之前和酒吧店员聊天,聊到了这座城市电影放映和唱片文化的现状,一致认为做得还不够。我说这不是一种批评,而是一种强烈的希望与期盼。我说,没有一个城市是文化沙漠,像这样的空间越来越多,这个城市的氛围才会越来越好,总要有人站出来做点什么。那晚大家相谈甚欢,每个人的眼里都闪着光
-
所以你问我写(创)作的心情到底是什么,我不想简单用几个词语将它标签化。正如我不喜欢给自己贴标签、下定义,而是希望你通过我的文字和面对面交流,对我形成一个初步印象
笼统一点讲,写(创)作的心情就是上面的文字传递出来的一股「劲」,它可以是冲劲也可以是丧劲,只要阅读我的文字就能真切地感受到。当然,创作同样也有尽头,只是目前它给我带来的新鲜感还很多。如果有一天,我失去了写(创)作的心情,或许就是真正要说再见的那天,一如 鱼缸咖啡闭店,这些是后话了
最后,在六周年的这个节点上,我希望自己能够怀着一份好心情出发,写点有趣的文字。无论是网络、游戏还是现实,如今都有一方空间存放我的精神世界,我很知足。也期盼大家找到自己的创作方向,勇敢地走出来表达自己。谢谢你阅读到这里。
频道:@NewlearnerChannel
🎈 写(创)作的心情——写在 Newlearnerの自留地成立六周年
除了第一年的短篇外,每年我都会在频道 8 月 12 日周年庆之前,写作一篇长文,聊聊这一年频道的情况和自己的感想。今年的情况比较特殊,出差完回来遇上亲人离世,没有了写作的心情,所以一直没有动笔
我对夏天的定义,通常是从可以穿短袖开始,到 8 月底结束。不仅仅是因为「处暑」了,而是学生开学、家长忙碌,天气逐渐转凉,失去了享受夏日的心情。所以我想着,在自己心中的夏天结束之前,还是为这个节点写点什么
✈️ 简单介绍一下情况
六周年,离七年之痒还剩一年,Telegram 和这个频道已疲态尽显,不过有时候慢下来并不是一件坏事
• 一年的订阅数增长可以忽略不计,频道和群组充斥着广告 Bot,大家加速逃离平台,新用户进入门槛不断提高,活人感降低
• 数码行业趋向稳定和瓶颈期,圈子已经形成且较为固定,难以流动。大多数人需求是看看实时新闻,不愿也没有时间进行进一步交流
• 频道许多板块停止更新,如「每日一摄」「每周觅食」「游戏周报」;其他周刊变动也较为频繁;往期新年活动以及周年庆征文均未达到预期效果,暂停举办
• 投稿和有意愿创作的人数越来越少,newsletters、播客、博客停更成风。从学生到社会人的身份转变,以及目前的社会形式,使得很多人压力很大、空余时间很少
• 新建了 2 个私密群组,一个聊「泛文娱」相关内容,另一个聊「游戏」相关内容,大家相处较为融洽。遗憾在于说了一年的电影、音乐分享期刊还没有做
• 频道逐渐「小而美」,由固定的几个人负责更新,大家安静地看
看上去坏消息多一些,不过这也是必然的结果。现在 AI 生成内容非常方便,文字、视频内容都卷出了新高度,选择太多就会导致走马观花。坚持创作的好处是,你能在感兴趣的领域不断深耕,不至于落入快节奏的陷阱
主编 Glaze 之前向我展示用 AI 生成的推送,似乎我们只需要负责选择题材,推送就能够自动生成。我和他讲,写作还是要「有人味」,有自己真实的想法。AI 比较适合用于客观事实的总结归纳和推理,但我们写作一定不是搬运这些东西,而是要有自己的观点
从「重启感性」开始,我就逐渐对于产品参数、对比祛魅,不再想过一种「客观理性」的人生。到了「顺流而下」,除了维持频道正常更新外,我主要在流媒体周报和周末总结中用一些文字表达自己近期的所思所想。大多数时间用来探索自己内心的精神世界,以及走出门外
-
新的一年,因为频道会员助力人数不够,我们停止了「每日一摄」的更新。这段时间里,自己精选了超过 5000 张日常照片存入 iCloud,也接触了各种品牌的数码相机、看了许多摄影展,最近还染上了胶片相机(机龄几乎和我一样大)。这是正确的创作的心情,即不是为了创作而创作,而是把创作当成了一种日常;阶段性地满溢,于是和大家分享
后来发现 Telegram 取消了对于频道 Level 2 的要求,无论是否助力都可以每天免费发送一张图片了。昨天试了一下,果然可行,但是被破坏的整个生态,以及失去的与投稿者之间的联系,就很难去修复和挽回了
后来随着足迹遍布许多城市乡村,我终于意识到「每周觅食」存在底层逻辑上的问题:分享者几乎被固定在某个城市(往往是一线),而我们的读者来自五湖四海,觅食推荐十分出彩却往往不具备参考性。这样的分享更应该发生在身边朋友之间,发生在经常拜访所在城市的网友之间。当年这个想法由我提出来,Sol 给予了高水平的开篇,如今我选择终结这个栏目,也谢谢所有参与分享的主编
或许是这几年看过了太多东西,逐渐对探店、出片这种小红书常见的生活方式祛魅,而是想自己创作点什么东西。朋友邀请我下个月去参观他的新家,包豪斯风格,我的第一想法是:或许以后可以以某个朋友的客厅餐桌作为基地,半个月或一个月相聚一次,大家自己带食材做饭、吃饭,聊聊近期感兴趣的话题,一起在客厅打打《马里奥派对》,然后留下一些文字和照片
-
说到疫情很多人都深恶痛绝,但正是因为大家居家无所事事,才开始关注并满足自己的精神需求。这期间自然而然就引发了对于线上社交的渴望,所以当年 Telegram、Clubhouse 都取得了不错的发展,自留地也借这股东风迎来了很多读者
但近几年大家的热情迅速消退了,就像这几年人们不会再谈论 Clubhouse 一样。一方面数码科技产品的发展,和频道的更新一样,几乎成为了一种定期要做的事,并且没有人能够一直高质量地生产新东西;另一方面,经济下行带来的工作压力使得很多人放弃了大部分爱好,也不再愿意在网络上表达自己或是与他人交流;此外,出门看世界成为了网络世界的最佳代餐,与其谈天说地不如说走就走
不过,最让我遗憾的就是,受限于 Telegram 注册门槛、封禁机制以及群聊活跃人群整体年龄段的影响,似乎很少有新高中生、大学生加入群聊和大家交流。老人不断离去,新的活水没有流入,河流就会逐渐干枯
乐观一点来看,目前几个水塘(群聊)都有它们各自的生态位和活跃者。创立频道起初是为了消除信息差,将自己看到的有价值的信息分享出来;后面逐渐更加关注个人成长、自我实现和精神世界,也是为了交友与人聊天;从来没有考虑过赢利,甚至自己贴了不少钱做活动。即便未来频道不更新了,依然能够找得到有趣的人聊天,目标其实已经达成
总之,目前你看到的一切都是经过取舍之后的结果,我的精力毕竟有限,也有自己的生活要过。骨子里,我还是喜欢分享、喜欢写作、喜欢折腾点新东西的。但这些将以一种怎样的质量和形式呈现在大家的面前,和写(创)作的「心情」息息相关
🧑🏻💻 写(创)作的心情
过去的许多年,我一直是一个情绪比较稳定的人,像一台机器一样高效运转。今年开始,不知道是不是因为时间变多、思考的问题变多,心情也开始变得多样,有好有坏。我常常和 理想之地 群友分享自己当下的心情,方式是用一首歌来代表
心情好的时候,譬如听到了还潮乐队那样的现场,亦或是在酒吧遇到了聊得来的店员,我就会进入「心流」。文思泉涌,金句频出,观点一个接着一个。无论是写作、摄影,跟着第一感觉走都能有不错的收获。心情好的时候,我更愿意输出,更愿意与他人建立连接
心情不好的时候,譬如过去的这一个多月,输出就不再定期运转了,我更喜欢停止输出、去寻找输入。正如去年「顺流而下」说的,不再要求按时按点地填满每一个档期,就像我现在不再强迫自己连续合上 Apple Watch 运动圆环一样。心情不好的时候,给自己放个假,出门看世界、与人倾诉,从音乐、电影中汲取养分
-
我最早的创作是从写作开始的,一开始在贴吧发帖分享,后面建立了自己的博客,再到自留地更新的这 6 年多,写作的字数应该远超百万。从一开始搬运新闻,分享一些客观的解决方案,到后来自己的表达愈发多样,不再局限于客观事实,喜欢讲讲故事、聊聊看法
后面发现文字是根基,但也是基础的表现形式。所以我开始用相机记录眼前所见,玩唱片机和吉他表达声音,开汽车带自己拜访异乡的风景和人群,最后再用文字记录下这一切。这样的模式玩得久了,终于意识到,作为一个消费者,对我来讲是远远不够的
去年冬天朋友们带菜来我家小聚,觥筹交错之间聊起了另一个朋友想要做自己空间(小店)的事情。我对此表示不理解,我说人生可以不断体验,你去上海会有最 TOP 的店可以感受。也即我们可以任意拜访有品位格调的地点,为什么要自己做一个更差的。朋友们年龄都比我大,大家安慰我说可能还要玩上几年,才能体会到这一点。他们说,消费总有尽头
用不了几年时间,今年我就意识到,消费者和创作者是两种不同的境界,获得的乐趣也相差甚远。我们自己办电影放映、唱片分享、DJ Remix、插电活动,做实体唱片墙、布置隔音和声学空间、采购舒适的座椅、设计调酒和灯光,真正把大家多年来的美学欣赏和个人品味,转化为了实体的东西。许多浅尝辄止的东西,当你开始想要表达,就必须垂直深挖,创作表达的同时也在不断学习。想做的东西还有很多,一场个人摄影展、一份音乐小报,甚至是一个分享做菜和喝酒的小客厅
这就好比「野鱼志」里面的一个个业余项目,受众不多但是有趣,就像自己的孩子一样。以石击水,能激起层层涟漪,只要开始创作和表达,会有越来越多有趣的人和事走到你面前。这是我去消费、去索取很难获得到的 —— 在他们眼中,我是那个有趣的过客,而我能获得什么只能由他们来主导。今年开始,我和朋友们决定夺回主动权,正如当年创立自留地的心情那样
之前和酒吧店员聊天,聊到了这座城市电影放映和唱片文化的现状,一致认为做得还不够。我说这不是一种批评,而是一种强烈的希望与期盼。我说,没有一个城市是文化沙漠,像这样的空间越来越多,这个城市的氛围才会越来越好,总要有人站出来做点什么。那晚大家相谈甚欢,每个人的眼里都闪着光
-
所以你问我写(创)作的心情到底是什么,我不想简单用几个词语将它标签化。正如我不喜欢给自己贴标签、下定义,而是希望你通过我的文字和面对面交流,对我形成一个初步印象
笼统一点讲,写(创)作的心情就是上面的文字传递出来的一股「劲」,它可以是冲劲也可以是丧劲,只要阅读我的文字就能真切地感受到。当然,创作同样也有尽头,只是目前它给我带来的新鲜感还很多。如果有一天,我失去了写(创)作的心情,或许就是真正要说再见的那天,一如 鱼缸咖啡闭店,这些是后话了
最后,在六周年的这个节点上,我希望自己能够怀着一份好心情出发,写点有趣的文字。无论是网络、游戏还是现实,如今都有一方空间存放我的精神世界,我很知足。也期盼大家找到自己的创作方向,勇敢地走出来表达自己。谢谢你阅读到这里。
频道:@NewlearnerChannel
今天的起床时间是--2025-08-28 04:20:27。
起床啦。
今天是今年的第 240 天。
█████████████░░░░░░░ 65.8% (240/365)
GitHub:
• 创建了 PR: gh-138170: traceback file maybe use local import for trace print (python/cpython)
• 创建了 Issue: 想做个 running_page 周边 (yihong0618/running_page)
• Star 了项目: nonebot/nonebot2
• Star 了项目: databendlabs/jsonb
Run:
• 昨天没跑
• 本月跑了 95.97 公里
• 今年跑了 892.06 公里
今天的一句诗:
丛菊两开他日泪,孤舟一系故园心。
起床啦。
今天是今年的第 240 天。
█████████████░░░░░░░ 65.8% (240/365)
GitHub:
• 创建了 PR: gh-138170: traceback file maybe use local import for trace print (python/cpython)
• 创建了 Issue: 想做个 running_page 周边 (yihong0618/running_page)
• Star 了项目: nonebot/nonebot2
• Star 了项目: databendlabs/jsonb
Run:
• 昨天没跑
• 本月跑了 95.97 公里
• 今年跑了 892.06 公里
今天的一句诗:
丛菊两开他日泪,孤舟一系故园心。
GitHub
gh-138170: traceback file maybe use local import for trace print by yihong0618 · Pull Request #138179 · python/cpython
This patch fix need to use system traceback for the error
if there's a local traceback.py we should ignore them
Issue: shadowing error with traceback module leads to unexpected code execu...
if there's a local traceback.py we should ignore them
Issue: shadowing error with traceback module leads to unexpected code execu...
👍2
Forwarded from Welcome to the Black Parade
我还是要赞美 @LeonHwang (gh: Asphaltt) 的 bpfsnoop。
我仔细 review 哪一步是运气,意识到 retsnoop 这一步就是狗屎运:
halfling 的好运,返回 EIO 的内核函数名正好在
这其实是个一般化的难题:已知用户态进程调用 syscall 报错,问内核为什么报错了。
retsnoop 已经算是很好的工具了,但还不够好,我仔细想了一会儿,意识到在 tracepoint 出口做 lbr trace 就是我想要的,而这 bpfsnoop 已经实现了。
预备,开始
完美的过滤,完美的输出,不任何一点运气,不需要一点 tty 的内核实现前置知识,只需要找到 syscall 入口函数 __x64_sys_ioctl,然后 bpfsnoop will guide you home.
我仔细 review 哪一步是运气,意识到 retsnoop 这一步就是狗屎运:
# sudo ./retsnoop -x EIO -a '*tty*' -e '*tty*'
10:10:44.178847 -> 10:10:44.178850 TID/PID 30657/30657 (python/python):
entry_SYSCALL_64_after_hwframe+0x76
do_syscall_64+0x7e
x64_sys_call+0x131e
__x64_sys_ioctl+0xa4
2us [-EIO] tty_ioctl+0x515
⌇ 1us [-EIO] n_tty_ioctl+0x85
⌇ 1us [-EIO] n_tty_ioctl_helper+0x2d
⌇ 0us [-EIO] tty_mode_ioctl+0x1c1
set_termios+0x5d
⌇ 0us [-EIO] tty_check_change+0x13
!⌇ 0us [-EIO] __tty_check_change
halfling 的好运,返回 EIO 的内核函数名正好在
*tty* pattern 里,所以直接过滤出来了。但凡运气平凡一点,恐怕还要在摸索个半小时的内核才能找到返回 EIO 的地方。这其实是个一般化的难题:已知用户态进程调用 syscall 报错,问内核为什么报错了。
retsnoop 已经算是很好的工具了,但还不够好,我仔细想了一会儿,意识到在 tracepoint 出口做 lbr trace 就是我想要的,而这 bpfsnoop 已经实现了。
预备,开始
$ sudo bpfsnoop -k __x64_sys_ioctl --output-lbr --filter-pid $(pidof python) --filter-arg 'retval==-5'
LBR stack:
[#31] is_current_pgrp_orphaned+0x4c -> __tty_check_change+0xd2
__tty_check_change+0xd6 -> __rcu_read_unlock+0x0
__rcu_read_unlock+0x24 -> __tty_check_change+0xdb
__tty_check_change+0xe0 -> __tty_check_change+0x30
__tty_check_change+0x46 -> tty_check_change+0x13
tty_check_change+0x18 -> set_termios+0x5d
set_termios+0x90 -> tty_mode_ioctl+0x1c1
tty_mode_ioctl+0x1c1 -> tty_mode_ioctl+0xc4
tty_mode_ioctl+0xf0 -> n_tty_ioctl_helper+0x2d
n_tty_ioctl_helper+0x3d -> n_tty_ioctl+0x85
n_tty_ioctl+0x95 -> tty_ioctl+0x515
tty_ioctl+0x537 -> tty_ldisc_deref+0x0
tty_ldisc_deref+0x11 -> ldsem_up_read+0x0
ldsem_up_read+0x1b -> tty_ldisc_deref+0x16
tty_ldisc_deref+0x19 -> tty_ioctl+0x53c
tty_ioctl+0x543 -> tty_ioctl+0x1e2
tty_ioctl+0x20e -> __x64_sys_ioctl+0xa4
__x64_sys_ioctl+0xac -> __x64_sys_ioctl+0x49
__x64_sys_ioctl+0x50 -> __x64_sys_ioctl+0x5a
__x64_sys_ioctl+0x6f -> bpf_trampoline_6442593479+0x31
完美的过滤,完美的输出,不任何一点运气,不需要一点 tty 的内核实现前置知识,只需要找到 syscall 入口函数 __x64_sys_ioctl,然后 bpfsnoop will guide you home.
Forwarded from Welcome to the Black Parade
Please open Telegram to view this post
VIEW IN TELEGRAM
🤗14👨💻3