终于有手机了
昨天开始使用手机了,终于跟上时代。
机子是老妈的 Nokia 8250 老爷机,能打电话能收发短信就够了。
上星期弄的,扔掉 icewm 了。桌面依然是 ROX-filer 的 pinboard,WM 是 Openbox,下面的 panel 是 fbpanel。原先想加上 conky,后来发现效果不佳,就去掉了。
Openbox 的配置文件是 xml 的,很易处理。我写了个 python 脚本配置主菜单。但一个问题是 Openbox 的主菜单无法直接在 panel 上调用,因为 panel 不是 Openbox 的。后来使用了 xdotool 解决了。
昨天跟骨头因为某些原因谈到了 linux 中进程的栈有多大的问题。从 ulimit -a 中可以看出,栈大小是 8M ,但经过试验,发现并非如此。看来唯有用实验的方法找了。
这是测试程序的代码
int main()
{
char a[S_SIZE];
a[0] = '\1';
return 0;
}
通过控制 S_SIZE 的值,观测程序是否因段错误崩溃,就可以大致知道栈空间有多大。至于寻找 S_SIZE,我使用了二分的方法。
但奇怪的是,寻找出来的 S_SIZE 的值竟然每次都不同,骨头他也发现当 a 的大小在某个区域(大约在 8380000 字节附近)时,程序段错误出现了随机性。实在太奇怪了。
既然出现了随机性,于是便统计了成功运行(即没有出现段错误)的概率和 a 大小的关系:(骨头供图,横坐标是 a 的大小,单位字节,纵坐标是成功概率,单位 %)
噢,看来是线性相关哦。根据老狼的解释,程序进入 main() 之前,先进入了 glibc 里的 _start(),并占用了部分的栈。如果是这样的话,留给 main() 的栈空间大小大概为 8376000Byte ~ 8384200Byte,且呈均匀分布(即栈大小为在此区间内各值的机率是均等的)。至于为什么会这样,可能跟 _start 的实现有关,就不清楚了。
附一篇 Before main() 分析。貌似很复杂,我没深入看。
昨天跟骨头研究栈大小的问题时,发现在栈上分配同样大小的数组,我的程序段错误了,骨头的竟然没事!怎么回事呢?我把他的程序拿来对比:
我的版本
int main (int argc, char const* argv[])
{
char a[8*1024*1024];
return 0;
}
骨头的版本
int main ()
{
char a[8*1024*1024];
return 0;
}
看来只有 main 的声明方式不同。但为什么我的就会崩溃呢,通过看汇编代码终于找到了原因。
先看骨头的版本
main: .LFB2: pushq %rbp .LCFI0: movq %rsp, %rbp .LCFI1: subq $8388488, %rsp .LCFI2: movl $0, %eax leave ret
然后是我的
main: .LFB2: pushq %rbp .LCFI0: movq %rsp, %rbp .LCFI1: subq $8388504, %rsp .LCFI2: movl %edi, -8388612(%rbp) movq %rsi, -8388624(%rbp) movl $0, %eax leave ret
看来那句数组声明并没有实际的“分配”空间,而只是简单的移动栈顶(%rsp)。而 gcc 又可能使用了某种调用协议,使用 %edi 和 %rsi 传递前两个参数,于是在把寄存器参数压到栈上时,就段错误了。
昨天是猫的 19 岁生日,我约了她一起去天河城打游戏机。我们兑了 60 个币,玩了一个多小时,只用了一半。呵呵,太开心了。不过收获不多,看见有人拿着几千张票,太无言了。
之后又去了购书中心,买了一本《The Art of UNIX Programming》。还记得当初第一次约她单独出来也是去购书中心呢,时间有时过得很快。
不过,我没有准备礼物,算是偷懒了一回吧。她也是叫我不用送礼物了。