SAN(Storage Area Network存储区域网络)和NAS(Network Attached Storage不知中文点译)都是提供网络存储的解决方案。
其中NAS是*一个*存储设备,以文件为操作单位。
SAN用一个局域网把很多设备连接起来,以磁盘的块(block)为操作单位。
SAN(Storage Area Network存储区域网络)和NAS(Network Attached Storage不知中文点译)都是提供网络存储的解决方案。
其中NAS是*一个*存储设备,以文件为操作单位。
SAN用一个局域网把很多设备连接起来,以磁盘的块(block)为操作单位。
在这里记下我的程序BUG
#调用getaddrinfo很多次以后,getaddrinfo报错:No address associated with NAME。非常地奇怪呀后来把同样的程序部署到比较旧的linux上,报错: Too many open files。才明白,原来fd被用光了。回头再检查相关代码,果然如此~补上close(fd)后,getaddrinfo的问题也解决了。启发是:1. 有些报错信息其实离真正的错误原因很远。2. 一个系统调用一开始正常,跑了很多次后失败,应该怀疑是不是有资源泄露。
#把uint_t类型赋值给std::string时,会崩溃在std::string里面。
#当一个预期统一的规则出现特例的时候容易出现BUG. 关联订单,关联片区,入货地址都指受YYYY-MM-DD HH:MM:SS的时间戳,但同机分析接受的时间戳却是YYYYMMDD某一天的时间戳。有一个组合需求是同时导出上述4个小需求时,由于传入的时间戳参数不一致导致了BUG.
# 用boost::optional记录一个信息。这个信息没及时在clear函数里做清理。于是,观察到的情况时,这个信息总是被打印。但一开始,我们却怀疑是另外的函数不稳定而重新生成了该信息。
原因是此布尔变量未被初始化,大多数时候它的值是false,但有时却不是。
#. 现象rmap_item泄露.
Fix it: 单链表插入新结点时指针操作出错。应该是new->rmap_list = item,被我写成 new->rmap_list = (item)->rmap_list.
#. 我意图注释掉某行代码,却鬼使神差注释错了一行代码。
#. 变量名 pkt 和ptr 很像,在用memcpy函数时用错了变量导致bug. 一块内存被莫名其妙的修改了,很有可能是因为像刚才这样写这块函数的参数填错了。
#. _sessions.erase(ite++);删除了_sessions维护的一个对象.对象的析构被调用,会有一连串对象的析构因此而被调用。这些对象中的指针很可能就失效了。但是,在代码的其它地方还能拿到这个指针。野指针啊!!!今天这个例子中是session维护的ip_pkt对象都被析构了,ip_pkt中的指针也都失效了。于是,一使用野指针,崩溃了。
#. 删除数据时,总是要注意其它代码中指向这些被删除数据的引用或指针。
#. 解引用container.end()返回的迭代器会崩溃。
#. 这是个腾讯视频广告投放组的bug. 一个线程负责开,关FD。另一个线程读写FD。两个线程的竞争条件造成了BUG.
#. 写代码时偷懒复制代码,然后忘记做相应更改,视觉上很难在第一时间察觉,却在后期花费了几倍时间调试程序。
#. 写判断语句时,判断表达示如 container.empty()之前是否要取反,经常搞错。
#. htonl 写成 htons
#. std::distance 计算两个迭代器之间距离时死循环,是因为迭代器没有初始化。而我之前想,作初始化工作的函数已经调用了,实际上并没有被调用。
#. 没注意函数的返回值. 有时函数返回0时表示成功,即true的含义。所以看到一些和预期刚好相反的现象时,应该考虑是不是出现了这样的错误。
#. 又是迭代器失效。erase(ite++), continue,但是for循环里有++ite。结果迭代器被加了两次。
#. 追踪到原因是野指针。野指针的特点是在调试器里会看到乱七八糟的值,如果只看一些标志变量会让人觉得颠覆了之前建立的逻辑,于是又去跟踪逻辑有没有问题。而这次bug,逻辑本身没错,而应该去找野指针是如何产生的。这次的野指针产生是因为负数取模后得到负数,又用这个负数作为索引去拿对象,结果拿到了无效的对象。这次的经验是,即使是超级简单的一些逻辑,觉得自己一定能保定索引是用效的,但一些不经意的代码给你生产了不合法的索引,于是花费大量时间追踪。对简单的判断多下诊断喔!
看来编译时出现警告要非常重视,一定要对警告的意义非常清楚,这极可能是出现BUG的原因。
昨天调了一整个晚上,各种离奇的出错~~
其实编译内核模块时,已经提示我警告了,但我一直没注意:
Building modules, stage 2.
MODPOST 1 modules
WARNING: modpost: Found 1 section mismatch(es).
To see full details build your kernel with:
'make CONFIG_DEBUG_SECTION_MISMATCH=y'
CC /home/zausiu/linux-3.0.66/mm/sksm/sksm.mod.o
LD [M] /home/zausiu/linux-3.0.66/mm/sksm/sksm.ko
警告告诉我使用 'make CONFIG_DEBUG_SECTION_MISMATCH=y'
我以为要编译整棵kenel sourcecode tree时打开DEBUG_SECTION_MISMATCH编译选项,在我的虚机里编译一次要几个小时啊,果断拒绝了。其实在内核代码树外单独编译内核模块时也只用DEBUG_SECTION_MISMATCH=y这个选项。
# make DEBUG_SECTION_MISMATCH=y
…
Building modules, stage 2.
MODPOST 1 modules
WARNING: /home/zausiu/linux-3.0.66/mm/sksm/sksm.o(.init.text+0x193): Section mismatch in reference from the function init_module() to the function .exit.text:sksm_slab_free()
The function __init init_module() references
a function __exit sksm_slab_free().
This is often seen when error handling in the init function
uses functionality in the exit path.
The fix is often to remove the __exit annotation of
sksm_slab_free() so it may be used outside an exit section.
至此,真相大白于天下~~ .init段的函数内调用了 .exist段的函数,把被调用函数去掉__exit指示即可!
//////////
至此,当出现离奇错误时。要高度重视编译时的警告,另外一个就是极有可能是因为竞争条件,还有个是栈溢出。
2 查询已安装的指定软件包的详细信息(dpkg -s)
使用"dpkg -s"命令查询ssh软件包的详细信息
3 查询系统中已安装的软件包所安装的文件(dpkg -L)
显示"ssh"软件包安装到系统的文件
debian:~# dpkg -L ssh
/.
/usr
/usr/share
/usr/share/doc
/usr/share/doc/openssh-client
/usr/share/doc/ssh
4 查询系统中的某个文件属于哪个软件包(dpkg -S)
debian:~# dpkg -S /etc/init.d/networking
netbase: /etc/init.d/networking
文件"/etc/init.d/networking"属于名为"netbase"的软件包。
debian:~# dpkg -S /etc/passwd
dpkg:没有找到 /etc/passwd。
系统中许多文件不属于任何软件包,它们可能是用户
山东莱芜方言高频词汇
作者: 高龙超 gaolch001@163.com
一、人称代词:
惩(音“恩”,ŋən):你,你们
俺(ŋan):我,我们
他(音近“特”,tə):他
二、时间名词:
1、日子
夜来:昨天
今(音“机”,tɕi)们:今天
明日:明天
后日:后天
大后日:大后天
2、早晚
早晨:早上
头晌午:上午
晌午:中午
光午:为“过晌午”的连读,意为下午
后晌:晌(音“赏”,sŋ)亦常读作航(hɔŋ)
3、时钟
钟头:小时
不大霎(音“杀”,sa):一会儿,不多时候,不长时间
大盼(pan)子:一大会儿,不超过半日
大会子:过了好久,一般指数月
三、动词:
1、与“家”有关
“家”作副词,表示动作的方向,该方向一般指自己的家。
家来:表示往“家”的方向而来,一般用来邀请其他人进入自己家
家去:表示往“家”的方向而去,“去”一般读作“气”,tɕʻi
家走:表示往“家”的方向而走,与“家去”相近,但“家走”更用来强调动作。
2、给(音“及”,tɕi)
表示“很”的程度副词:
(1)“精”,形容“小”及相近的词:
精短 精细 精窄 精矮(音近“眼”,iai)精浅 精薄 精瘦
该组多用ABB式叠词,比如“精短”可以说“精短短”
(2)“大”,形容“大”及相近的词:
大长 大粗 大厚(该组多用ABB式叠词)
(3)“乔”含有让人难以忍受的意思。
乔冷、乔热、乔苦、乔脏、乔酸、乔硬、乔辣、乔臭、乔难受、乔不得劲、乔肚子疼。
(4)“详”, 多有赞叹之意
详肥、详瘦、详干净、详富、详好。
(5)“怪”,它的语用域很广,只要普通话中能和副词“很”结合的词都能和“怪”结合。
怪沉、怪香、怪高、怪痛快、怪好
(6)“忒”,近似于普通话的“太”,一般表示程度有点过。
忒大、忒小、忒酸、忒甜、忒干净、忒窝囊
(7)“挺”,一般只能修饰“湿”和“浓”(泥泞)。
(8)其他固定搭配副词
焦酸 焦黄 焦干 焦劲 齁咸 稀甜 稀烂 稀软
锃明 锃白 锃绿 乌黑 红黑 齁辣
四、发音特点
1、声母:
(1)普通话的zh,ch,sh,r基本上读成平舌音z,c,s,?,普通话的z,c,s基本上读成咬舌音?,θ,?。
普通话的w声母大都读成唇齿音v。
(2)后面接u, ə时,部分r声母读成l
容 (音“龙”)luŋ ,褥(音“陆”)lu , 乳(音“鲁”)lu ,软(音“卵”)luan
(3)普通话的零声母基本全部改为ŋ声母
俺ŋan, 爱 ŋai, 摁 ŋen ,袄 ŋɔ
2、韵母:
(1)以下字均为ei (近-ik)作为韵母:
得 dei 德 dei 客 kei 责 zei 白 bei 百 bei 色 sei 麦 mei 摘 zei 册 cei 策 cei 墨 mei 脉 mei 宅 zei 迫 pei 柏 bei 拍 pei 窄 zei 刻kei 塞 θei
(2)以下字均以-uə结尾:
药(音“约”)iuə 薄buə 脚tɕuə 博buə 钥(音“月”)iuə 着zuə 勺suə
(3)前后鼻音与普通话不同的字:
怎 dzəng
暖 nang
懂 dun
甭 bən
吗 mang
嘛 man
吧 bə
(4)了
句中用lɔ(唠),句尾用liə(咧)。
五、其他习惯:
1、一般不用“死”字,普通话中有“死”这的,一般有“煞”(音“舌”,sa)。如:
气煞我咧:气死我了
喜煞我咧:笑死我了
冻煞咧:冻死了
关煞门:关死门(即:关上门)
2、普通话的“亮”一般改用“明”
明天了:天亮了
月明:月亮
锃明:锃亮
明快:明亮
今天写内核代码时要写一个比较两个页框(Page Frame)的函数,想到用内联汇编来写这个功能。下面是代码:
long cmp_x64(void *s1, void *s2, size_t n)
{
size_t num = n / 8;
register long res;
__asm__ __volatile__
(
"testq %3,%3\n\t" ; 测试num是不是0
"repe cmpsq\n\t" ; 不停地比较直到cx寄存器为0或比较到差别
"je 1f\n\t" ; 两块内存相等,跳出,返回0.
"sbbq %0,%0\n\t" ; sbb是x86的减法指令,会额外地减去CF(借位)的值,这样%0就会是0或者-1
"orq $1,%0\n" ; 把立即数1或到%0上,这样%0就会是1或者-1.
"1:"
: "=&a"(res) ; 传入变量res放入寄存器ax,且这个变量是输出值(=),不要与其它输入输出共用寄存器(&)
: "0"(res), "S"(s1), "D"(s2), "c"(num) ; 输入列表
: "cc"); // clobber list 告诉gcc在这段内联汇编中哪些寄存器被显式/隐式修改.If our instruction can alter the condition code register, we have to add "cc" to the list of clobbered registers.
return res;
}
Linux内核中的宏可变参数(GCC的宏可变参数)。 写内核模块的时候为了调试方便,经常需要wrap一下printk函数。下面的宏定义非常有实用价值。 注意两个井号~~ 记到博客里~~ #define seclvl_printk(verb, type, fmt, arg...) \ do { \ if (verbosity >= verb) { \ static unsigned long _prior; \ unsigned long _now = jiffies; \ if ((_now - _prior) > HZ) { \ printk(type "%s: %s: " fmt, \ MY_NAME, __FUNCTION__ , \ ## arg); \ _prior = _now; \ } \ } \ } while (0)
我的debian一般把LC_ALL设成en_US.UTF-8。这次dpkg-reconfigure locales时没有选美国英语,而是用了香港英语。于是就出错了。
解决方法的关键在于 /etc/environment 文件, dpkg-reconfigure locales 命令用来配置local,以及locale命令列出当前期待的locale,还有 local-gen 命令可以生成local.
debian报得错误类似于:
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = "en_US:en",
LC_ALL = (unset),
LANG = "en_US"
are supported and installed on your system.
////////////
另外今天还解决了编译内核后,用新内核启动时报错:
kernel panic – not syncing VFS: unable to mount root fs on unknown block (0, 0)
// 通常这是因为对应文件系统被编译成模块,那么就应该生成initrd加载对应的文件驱动模块。在debian下,用update-initramfs 命令生成对应的initrd. 如: update-initramfs -c -k 3.0.63
git log -Sstring 这里的-S选项被称作pickaxe,这是一个非常好的排错工具。
比如: git log -Sinclude –pretty=oneline –abbrev-commit init/version.c
会把减少了,或者增加了include的commit全部找出来。
要注意的是,如果有一个提交增加和减少include的次数一样,这个commit不会被列出来。
/////////////
另外一个排错工作是 git blame:
git blame可以用来帮助查找引入bug的commit。git blame告诉你谁,什么时候,是哪个commit更改了某个文件。
如: git blame -L 32, init/version.c
调试内核很麻烦,即使是有了虚拟机的帮助。在这里记下一些关键的东西,以备忘 。
# 编译内核后, 用新内核启动系统失败,报错 “unable to mount fs ….” 之类.
需要用 update-initramfs 生成initram。
# 对于grub2,我增加了一个自定义的grub开机启动项用来调试内核,如下:
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
echo "Add Debugging entry"
cat << EOF
menuentry "Debian debug 3.7.4"{
set root=(hd0,1)
linux /boot/vmlinuz-3.7.4 root=/dev/vda1 ro quiet kgdboc=ttyS0,115200 kgdbwait
initrd /boot/initrd.img-3.7.4
}
EOF
/////////
the above grub configuration file resides in /etc/grub.d/
# client在虚拟机里启动后在内核调试断点处停下。这时在host机用gdb调试.
# gdb vmlinux
set remotebaud 115200
target remote /dev/pts/0
此时gdb输入continue命令让客户机的系统继续运行。如果想断下正在运行的client内核,在client机中使用magic SysR: echo "g" > /proc/sysrq-trigger