周末去广州看了下眼睛,被医生确诊为玻璃体后脱离

有句话叫久病成医,自己的眼睛问题,仔细端量下可分为几个

  1. 视疲劳
  2. 干眼症
  3. 近视

眼睛后侧,视网膜处并没有神经,导致眼睛痛的主要原因,应该是视疲劳.

看到的各种絮状条状或点状的floater,大部分是玻璃体后脱离导致的,想必也有一部分拜干眼症所赐.在医院测的泪液分泌表明并不存在干眼症,分泌速度甚至比正常人还要快.我想应该是在电脑前时间太多,眨眼次数太少导致干涩感的.

最后,近视,每个眼睛的视力大致在0.5左右,属于中度近视,不算什么问题.我已经习惯性的不戴眼镜并熟悉了模糊的世界.

几个让人头疼的症状,一个是玻璃体混浊,近一年来floater一直增多,飘来飘去,令人很郁闷.另一个是小闪光点,由于玻璃体后面跟视网膜有些分离但还未完全分开,来回推拉视网膜,使得视网膜向大脑传送微小电流,产生出来满视野的小点.

主要的两点,视疲劳导致的疼痛和玻璃体后脱离导致的floater和flash,是最让人frustrating的.一度在纠结是否要辞职回家休养半年.

ps:关于玻璃体后脱离,这里有一篇很好的介绍文章

最近在mac写代码比较多,以前用windows因为眼睛不好,就写了个程序,每隔几十分钟提示休息下。对着mac也觉得有必要搞个类似的东西。
在windows下的主要思路是开个WM_TIMER,然后在系统托盘显示个图标,一直不退出在后台运行,到时间了就在桌面上打印出REST YOUR EYES之类的大字。开始也想在mac上照这个思路做。不过今天在shell敲着命令突然灵光一现,于是就有了下面的这几行bash脚本
[code lang=”bash”]
#!/bin/bash

while [ 1 ]
do
sleep 600 && say rest your eyes
done
[/code]
还是unix的shell功能强大啊,几行脚本就搞定了;-)
btw,mac下的say命令真的很好用,可以把文本读出来,自动合成的语音效果还不错,结合各种命令就能得到十分有意思的效果

之前写过的一个协议解析生成的程序,在windows下用gcc和lex&yacc编译,运行的很好,到了mac下很多问题,先是直接syntax error,仔细排查后发现是之前文件换行用的是CRLF,改了能解析了,结果直接给出个Segmentation fault,折腾了整整一个下午加半个晚上,在每一个值得怀疑的地方加打印信息,最诡异的是,两个函数里的指针的值相同,一个正常,另一个就access violation。
[code lang=”c”]

void* set_comment(struct Entry* ent,char* cmt)
{
strcpy(ent->comment,cmt);
if (strlen(cmt)>0 && cmt[strlen(cmt)-1]==’n’)
ent->comment[strlen(cmt)-1] = ‘\0’;
return ent;
}

void* struct_entry(void* st,char* name,char* arr,char* swname)
{
struct Entry* ent = (struct Entry*)malloc(sizeof(struct Entry));
char* tname = ((struct TypeDesc*)st)->tname;

strcpy(ent->tname,tname);
strcpy(ent->name,name);
strcpy(ent->sw,swname);
strcpy(ent->arrval,arr);

return ent;
}
[/code]
struct_entry里申请struct Entry* ent的内存,返回又被传到了set_comment里面,打印出来两个地址相同,在set_comment就直接指针访问越界了。
最后用gdb一步步调,打印出来两个指针之后才发现,两个指针都是64位的,其中一个被截断了
ent is 100102210
ent is 102210
一开始printf的时候用的是%x,只有后面四个字节,所以相同。
但是为什么会被截断呢,指针返回是64位,传来传去应该都是正常的。在yacc的语法定义里是这么写的
[sourcecode language=”plain”]
st ID arr switchval { $<pval>$ = struct_entry($<pval>1,$<pval>2,$<pval>3,$<pval>4); }
[/sourcecode]
每个地方都貌似不存在问题。在这个执行规约的地方打印,返回的pval确实被截断了,于是开始怀疑是返回值声明导致的问题,找啊找,才发现这个函数没有在头文件里声明,而该死的gcc居然直接链接了,默认C的语法,也许在c89之前,应该是允许不声明直接调用的,默认返回值是int,这个被编译器认为是32位的长度,所以被截断了。

mac是64位的系统,编译出来后,void*之类的指针都是8个字节,int是4个字节,long long是8个。

这个bug差不多算是最近一两年来最让我头疼的一个了,不过最终还是解决了,mac用久了,越来越上手了。