存档

作者存档

web3.0和新信息时代

2011年4月14日 1 条评论

最近看到一篇好的文章,感觉很不错,想与大家分享。(同时从这篇文章中也发现了做数据挖掘大有可为-_-)

4月10号techcrunch上有一篇文章“The New information Age”讲到了web3.0的特征和新信息时代的一些特点:真实的用户产生海量的数据。如何利用这些数据应该是下一次信息浪潮的热点。不仅仅这篇文章不错,下面的评论也很有意思,其中一个人说:

The Web has 3 fundamental components:
- Content/Data
- People and.
- Communications- the interaction between the first two components.
While Web 1.0 solved the Content/Data part and Web 2.0 brought People online, the 3rd critical part of the Web – Real-time Communications has not been solved.

我已经深切的感受到了现在的互联网的信息越来越真实,facebook的5亿用户大部分都提供真实的信息。国内的人人网,开心网上面的信息也越来越真实,sina微博的加V服务,很多不加v的用户也提供真实的信息和头像。互联网已经成为社会的一个延伸,很多人把互联网作为个人品牌传播的媒介,以前的那种在网上聊天不知道对方是人还是狗的时代已经一去不复返了。facebook在国外已经成为了一种身份认证服务,人们在网上行为也越来越规范,创造的信息也越来越有价值(真实身份下面大家都会维护自己在网上的声誉)。

目前互联网(或者说整个人类世界)的数据越来越多,多到一辈子只能利用其中百万分之一甚至更少的数据,如何找到有用的信息,如何更智能的利用更多的信息,都是迫切而现实的问题。目前利用这些海量信息的方式还非常原始,新的浪潮需要技术大的突破,在这个领域应该会产生很多伟大的公司。

国内有人翻译了新信息时代这篇文章,http://www.36kr.com/a-new-information-age/,翻译的质量还可以,但是评论的质量不如techcrunch上的用户。

Popularity: 23%

linux 中查看某个单进程程序运行所占内存(linux proc status statm详解)

2011年4月8日 没有评论

linux 中查看 某个单进程程序运行所占内存所占的内存空间,设pid为进程id(ps aux| grep ‘processName’获得),查看/proc/pid/statm和/proc/pid/status即可

proc/[pid]/statm
              Provides information about memory usage, measured in pages.  The
              columns are:

                  size       total program size
                             (same as VmSize in /proc/[pid]/status)
                  resident   resident set size
                             (same as VmRSS in /proc/[pid]/status)
                  share      shared pages (from shared mappings)
                  text       text (code)
                  lib        library (unused in Linux 2.6)
                  data       data + stack
                  dt         dirty pages (unused in Linux 2.6)

       /proc/[pid]/status
              Provides much of the information in /proc/[pid]/stat and
              /proc/[pid]/statm in a format that's easier for humans to parse.
              Here's an example:

                  $ cat /proc/$$/status
                  Name:   bash
                  State:  S (sleeping)
                  Tgid:   3515
                  Pid:    3515
                  PPid:   3452
                  TracerPid:      0
                  Uid:    1000    1000    1000    1000
                  Gid:    100     100     100     100
                  FDSize: 256
                  Groups: 16 33 100
                  VmPeak:     9136 kB
                  VmSize:     7896 kB
                  VmLck:         0 kB
                  VmHWM:      7572 kB
                  VmRSS:      6316 kB
                  VmData:     5224 kB
                  VmStk:        88 kB
                  VmExe:       572 kB
                  VmLib:      1708 kB
                  VmPTE:        20 kB
                  Threads:        1
                  SigQ:   0/3067
                  SigPnd: 0000000000000000
                  ShdPnd: 0000000000000000
                  SigBlk: 0000000000010000
                  SigIgn: 0000000000384004
                  SigCgt: 000000004b813efb
                  CapInh: 0000000000000000
                  CapPrm: 0000000000000000
                  CapEff: 0000000000000000
                  CapBnd: ffffffffffffffff
                  Cpus_allowed:   00000001
                  Cpus_allowed_list:      0
                  Mems_allowed:   1
                  Mems_allowed_list:      0
                  voluntary_ctxt_switches:        150
                  nonvoluntary_ctxt_switches:     545

              The fields are as follows:

              * Name: Command run by this process.

              * State: Current state of the process.  One of "R (running)", "S
                (sleeping)", "D (disk sleep)", "T (stopped)", "T (tracing stop)", "Z
                (zombie)", or "X (dead)".

              * Tgid: Thread group ID (i.e., Process ID).

              * Pid: Thread ID (see gettid(2)).

              * TracerPid: PID of process tracing this process (0 if not being
                traced).

              * Uid, Gid: Real, effective, saved set, and file system UIDs (GIDs).

              * FDSize: Number of file descriptor slots currently allocated.

              * Groups: Supplementary group list.

              * VmPeak: Peak virtual memory size.

              * VmSize: Virtual memory size.

              * VmLck: Locked memory size (see mlock(3)).

              * VmHWM: Peak resident set size ("high water mark").

              * VmRSS: Resident set size.

              * VmData, VmStk, VmExe: Size of data, stack, and text segments.

              * VmLib: Shared library code size.

              * VmPTE: Page table entries size (since Linux 2.6.10).

              * Threads: Number of threads in process containing this thread.

              * SigPnd, ShdPnd: Number of signals pending for thread and for process
                as a whole (see pthreads(7) and signal(7)).

              * SigBlk, SigIgn, SigCgt: Masks indicating signals being blocked,
                ignored, and caught (see signal(7)).

              * CapInh, CapPrm, CapEff: Masks of capabilities enabled in inheritable,
                permitted, and effective sets (see capabilities(7)).

              * CapBnd: Capability Bounding set (since kernel 2.6.26, see
                capabilities(7)).

              * Cpus_allowed: Mask of CPUs on which this process may run (since Linux
                2.6.24, see cpuset(7)).

              * Cpus_allowed_list: Same as previous, but in "list format" (since
                Linux 2.6.26, see cpuset(7)).

              * Mems_allowed: Mask of memory nodes allowed to this process (since
                Linux 2.6.24, see cpuset(7)).

              * Mems_allowed_list: Same as previous, but in "list format" (since
                Linux 2.6.26, see cpuset(7)).

              * voluntary_context_switches, nonvoluntary_context_switches: Number of
                voluntary and involuntary context switches (since Linux 2.6.23).

示例代码下载

Popularity: 52%

分类: C++, linux 标签:

推荐系统评估指标和实验方法

2011年4月8日 4 条评论

前言:本文总结推荐系统用到的评估指标和实验方法,当做自己学习推荐系统的一个学习笔记吧,欢迎大家补充一些新的方法,本文也会不断更新

评估指标:

1、MAE

2、RMSE

3、Precision-Recall 曲线(TOP-K推荐常用)和AUC(area under curve)

4、NDCG(Normalized Discounted Cumulative Gain),一种评价top-k推荐的方法,来源于搜索引擎搜索结果的评价指标

5、可解释性(explanation),这个往往是模型本身的特点决定的

6、多样性(diversity),具体公式???

7、惊喜度(serendipity),具体公式??

8、置信系数(confidence),这个还没有弄明白,不过已经具体知道几篇论文介绍这个方面

实验测试方法:

1、离线测试

(1)把数据集分成训练集和测试集,在训练集上训练模型参数,在测试集上测试

(2)

2、在线测试

(1)A/B test

(2)

3、用户调研(user studies)

就是找一批测试用户,记录他们在特定情况下的反应,问他们的反馈,

参考文献:
1、Recommender System Handbook  chapter 8

2.   zheng H, Do clicks measure recommendation relevancy?: an empirical user study

Popularity: 43%

分类: 推荐系统 标签: ,

推荐系统算法实现的开源project发布(implementations of classic algorithms in recommender system)

2011年4月6日 8 条评论

在实现koren论文的算法的时候我遇到了很多问题:

(1)针对大规模数据的时候(100M的打分数据),以前那种粗放型的使用cpu和内存的方法完全行不通,因为数据量大,算法和数据结构不考虑周到则时间和空间消耗都难以忍受。

(2)数据的初始化和参数的设置对结果有很大的影响,为了复现koren的结果,我第一个svd的程序大概花了2周时间才搞定,中间走了很多弯路,光调参数就花了4天。

(3)其他一些困难,此处省略1000字-_-……

为了减少推荐系统领域的朋友入门的难度,我将一些推荐算法的细节展现出来,通过代码的形式呈现给大家,给大家一个好的参照,使大家能尽快上手,减小入门的门槛,希望能为推荐系统领域的发展尽一些绵薄之力!希望有更多的人研究这个有趣且有用的领域!

代码说明:

(1)所有的代码都是用c++实现(c++效率高,对于像netflix dataset这么大规模的数据,脚本语言处理起来太慢)

(2)代码使用GPL V3协议发布,大家在使用的时候请保留版权信息。

(3)代码中肯定有很多不完善和错漏的地方,如果发现,请给我发邮件,也希望大家和我一起完善这个project。

一些有用的链接

(1) 新人第一步:快速使用本project的入门指南

(2) 获取本project中用到的netflix的测试集和训练集数据的方法:netflix数据预处理方法

(3) 在代码实现过程中遇到的问题

(4) knn算法执行的一些结果

(5) svd算法执行的一些结果

希望有更多的人加入这个project,将更多的算法代码贡献出来,比如目前尚缺RBM model,temporal model

想加入开发的或者交流的朋友可以从这里很方便的联系我:我的联系方式 或者直接给我发mail,honglianglv at gmai的邮箱

Project的地址: http://code.google.com/p/recsyscode/

ps: 这也是我的第一个开源项目,用了这么多的开源软件,今天算是迈出了回馈开源界的第一步,以后如果有好的东西我也会分享给大家

Popularity: 66%

netflix dataset 下载(download)

2011年4月3日 7 条评论

netflix已经不提供数据集下载了,但是很多做推荐系统的朋友还是想在netflix数据集上面做实验,验证一些想法或者是学习一些经典算法。现在提供下载,希望大家尽量采用单线程下载,总大小666M。

点击这里下载

PS:一切版权归netflix所有,我这里只是给大家提供一些方便,这是一个原始的完整的数据包,包括了netflix的版权声明,如果有人认为提供下载不合适,侵犯了netflix的版权,可以随时给我发邮件,我去掉这个链接。

english version:

netflix does not provide dataset now, but there are also many friends who want the dataset to  verify some new ideas or to learn some classic recommender system algorithms.  Now I provide the dataset as follows:( hope you use single-thread to download,  the total size of the dataset is  666M).

Click here to download

PS: All rights reserved  by netflix.  I  only provide  some convenience to the researcher of recommender system. The dataset is an original and complete one,  including the netflix’s copyright notice.

Popularity: 100%

推荐学习曾国藩&学习曾国藩的方式

2011年3月3日 4 条评论

版权声明:本文纯属原创,转载请注明出处!

去年11月份在我感觉最痛苦最无助的时候看到了曾国藩家书,从此开始了对曾国藩的了解,了解曾国藩对我走出困境,树立正确的价值观起到了非常积极的作用,独乐乐不如与众乐乐,我想把曾国藩推荐给大家。

曾国藩维基百科介绍:http://zh.wikipedia.org/zh-cn/%E6%9B%BE%E5%9B%BD%E8%97%A9

名人对曾国藩的评价:

·毛泽东: 愚于近人,独服曾文正!
毛泽东十六岁时在湘乡东山高小读书,并在这里通读了光绪年间出版的《曾文正公全集》。他读过的《曾文正公全集》,至今还保留在韶山毛泽东纪念馆。l917 年,毛泽东在通读《曾文正公全集》之后,对中国历史上的大人物进行了一番研究,得出了“愚于近人,独服曾文正”的结论。毛泽东在写给好友萧子升的信中曾提 到:尝诵程子之箴,阅曾公(即曾国藩)之书,上溯周公、孔子之训,若曰惟口兴戎,讷言敏行,载在方册,播之千祀。
· 蒋介石: 《曾文正公全集》,任何政治家必读!
蒋介石案头常年摆着一套《曾文正公全集》,时时翻阅,一生都在研究它。他准备了很多套《曾文正公全集》,经 常拿来作为奖赏送人。  蒋介石一生推崇、学习、效仿曾国藩,认为曾国藩的著作“是任何政治家所必读的”。
·梁启超: 吾谓《曾文正集》,不可不日三复也!
梁启超对曾国藩推崇备至:曾文正者,岂惟近代,盖有史以来不一二睹之大人也已;岂惟我国,抑全世界不一二睹 之大人也已。在《饮冰室文集•新民说》中,他如此评价《曾文正公全集》:吾党不欲澄清天下则已,苟有此志,则吾谓《曾文正集》,不可不日三复也。

我们已经知道学习曾国藩对我们很有好处,那么学习曾国藩最快捷的方式是什么呢?我认为学习知识就像炖肉,首先用大火炖,然后用小火焖,如此烹调,味道才能全部出来。读曾国藩也是这样,首先看传记了解其大概,然后看家书,日记,奏章,了解其细节。

观其大略(大火炖):

(1)       百科全书:

维基百科:http://zh.wikipedia.org/zh-cn/%E6%9B%BE%E5%9B%BD%E8%97%A9

百度百科http://baike.baidu.com/view/5481.htm

(2)       年谱:http://www.gf08.com/zgf/zgfnp2.htm ,如果有条件看看年鉴更好,在《曾文正公全集》第一卷有。

(3)       清史稿曾国藩传:http://www.guoxue.com/shibu/24shi/qingshigao/qsgx_405.htm

(4)       唐浩明的《曾国藩传》:(点击下载:唐浩明-曾国藩传

110331重要更新 感谢xm4s 推荐的萧一山的《曾国藩传》,这才是真正的好的曾国藩传记,比唐浩明的那本高几个档次,点击这里下载

(5) 张弘杰的《曾国藩的正面与侧面》,非常好的书,强烈推荐!!!!

网上可以看到一半的内容,可以先看后买。http://www.tianya.cn/publicforum/content/no05/1/181190.shtml ,购买可以去京东或者卓越

ps:大火炖的要诀在于快,快速浏览曾国藩的生平和概貌,对理解他的书信,日记,奏章,批牍都有好处

了解细节(小火焖):

1、  曾国藩家书:先看精选,再看全集

精选:唐浩明的《唐浩明点评曾国藩家书》

全集:《曾国藩家书全集》,推荐岳麓书社版本,如果没有的话北京燕山出版社的也可以凑合。

2、  《曾文正公全集》传忠书局版,梁启超,毛泽东,蒋介石看的就是这个版本

3、  《曾国藩全集》岳麓书社版

PS:小火焖阶段要诀在慢,一天看家书不超过5篇,2篇为宜,细细体会,把学习曾国藩当成一辈子的事情,不在于看得多,而在于自己理解收获的多少,边看边思考,要真正的有收获。等看完家书全集,甚至选集。应该就会有自己的体会,剩下的怎么学习就看自己的个人兴趣了。

祝大家在学习曾国藩的过程中感受到自我升华的快感,哈哈哈!

点击下载:唐浩明-曾国藩传

Popularity: 17%

分类: 修身, 生活 标签:

STL中list,vector,deque,map,set区别、联系和使用场景

2011年3月3日 没有评论

版权声明:本文某些内容来源于互联网,经过自己整理、编辑和总结成文,谢谢csdn,谢谢 google

vector和built-in数组类似,它拥有一段连续的内存空间,并且起始地址不变,因此
它能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间
进行插入和删除会造成内存块的拷贝,另外,当该数组后的内存空间不够时,需要重新
申请一块足够大的内存并进行内存的拷贝。这些都大大影响了vector的效率。

list就是数据结构中的双向链表(根据sgi   stl源代码),因此它的内存空间可以是不连续
的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它
没有提供[]操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除
和插入。

deque是一个double-ended   queue,它的具体实现不太清楚,但知道它具有以下两个特点:
它支持[]操作符,也就是支持随即存取,并且和vector的效率相差无几,它支持在两端的
操作:push_back,push_front,pop_back,pop_front等,并且在两端操作上与list的效率
也差不多。

Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性map内部的实现自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能。

set是集合,set中不会包含重复的元素,这是和vector的第一个区别,第二个区别是set内部用平衡二叉树实现,便于元素查找,而vector是使用连续内存存储,便于随机存取。
因此在实际使用时,如何选择这几个容器中哪一个,应根据你的需要而定,一般应遵循下面
的原则:
1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。

4、如果你要存储一个数据字典,并要求方便地根据key找value,那么map是较好的选择

5、如果你要查找一个元素是否在某集合内存中,则使用set存储这个集合比较好

参考文献:
1、http://topic.csdn.net/t/20011226/08/442147.html

2、http://41620935.blog.163.com/blog/static/498206420082185032531/

Popularity: 43%

分类: C++ 标签: , , , , , ,

【转】Linux下的段错误产生的原因及调试方法

2011年3月1日 没有评论

编者按:最近用gdb调试程序,发现功能还是比较强大的,下面是gdb调试段错误的一些方法

这篇文章好多地方都有,最早的我看到的是这个,我也是从这里转的:http://www.upsdn.net/html/2006-11/775.html

简而言之,产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其常见的是访问0地址.

一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中以及程序的在cpu中的运行级别,指向的gdt是由以64位为一个单位的表,在这张表中就保存着程序运行的代码段以及数据段的起始地址以及与此相应的段限和页面交换还有程序运行级别还有内存粒度等等的信息。一旦一个程序发生了越界访问,cpu就会产生相应的异常保护,于是segmentation fault就出现了.

在编程中以下几类做法容易导致段错误,基本是是错误地使用指针引起的

1)访问系统数据区,尤其是往  系统保护的内存地址写数据
最常见就是给一个指针以0地址
2)内存越界(数组越界,变量类型不一致等) 访问到不属于你的内存区域

解决方法

我们在用C/C++语言写程序的时侯,内存管理的绝大部分工作都是需要我们来做的。实际上,内存管理是一个比较繁琐的工作,无论你多高明,经验多丰富,难 免会在此处犯些小错误,而通常这些错误又是那么的浅显而易于消除。但是手工“除虫”(debug),往往是效率低下且让人厌烦的,本文将就”段错误”这个 内存访问越界的错误谈谈如何快速定位这些”段错误”的语句。
下面将就以下的一个存在段错误的程序介绍几种调试方法:

1  dummy_function (void)
2  {
3          unsigned char *ptr = 0×00;
4          *ptr = 0×00;
5  }
6
7  int main (void)
8  {
9          dummy_function ();
10
11          return 0;
12  }

作为一个熟练的C/C++程序员,以上代码的bug应该是很清楚的,因为它尝试操作地址为0的内存区域,而这个内存区域通常是不可访问的禁区,当然就会出错了。我们尝试编译运行它:

xiaosuo@gentux test $ ./a.out
段错误

果然不出所料,它出错并退出了。
1.利用gdb逐步查找段错误:
这种方法也是被大众所熟知并广泛采用的方法,首先我们需要一个带有调试信息的可执行程序,所以我们加上“-g -rdynamic”的参数进行编译,然后用gdb调试运行这个新编译的程序,具体步骤如下:

xiaosuo@gentux test $ gcc -g -rdynamic d.c
xiaosuo@gentux test $ gdb ./a.out
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB.  Type “show warranty” for details.
This GDB was configured as “i686-pc-linux-gnu”…Using host libthread_db library “/lib/libthread_db.so.1″.

(gdb) r
Starting program: /home/xiaosuo/test/a.out

Program received signal SIGSEGV, Segmentation fault.
0×08048524 in dummy_function () at d.c:4
4               *ptr = 0×00;
(gdb)

哦?!好像不用一步步调试我们就找到了出错位置d.c文件的第4行,其实就是如此的简单。
从这里我们还发现进程是由于收到了SIGSEGV信号而结束的。通过进一步的查阅文档(man 7 signal),我们知道SIGSEGV默认handler的动作是打印”段错误”的出错信息,并产生Core文件,由此我们又产生了方法二。
2.分析Core文件:
Core文件是什么呢?

The  default action of certain signals is to cause a process to terminate and produce a core dump file, a disk file containing an image of the process’s memory  at the time of termination.  A list of the signals which cause a process to dump core can be found in signal(7).

以 上资料摘自man page(man 5 core)。不过奇怪了,我的系统上并没有找到core文件。后来,忆起为了渐少系统上的拉圾文件的数量(本人有些洁癖,这也是我喜欢Gentoo的原因 之一),禁止了core文件的生成,查看了以下果真如此,将系统的core文件的大小限制在512K大小,再试:

xiaosuo@gentux test $ ulimit -c
0
xiaosuo@gentux test $ ulimit -c 1000
xiaosuo@gentux test $ ulimit -c
1000
xiaosuo@gentux test $ ./a.out
段错误 (core dumped)
xiaosuo@gentux test $ ls
a.out  core  d.c  f.c  g.c  pango.c  test_iconv.c  test_regex.c

core文件终于产生了,用gdb调试一下看看吧:

xiaosuo@gentux test $ gdb ./a.out core
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB.  Type “show warranty” for details.
This GDB was configured as “i686-pc-linux-gnu”…Using host libthread_db library “/lib/libthread_db.so.1″.

warning: Can’t read pathname for load map: 输入/输出错误.
Reading symbols from /lib/libc.so.6…done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2…done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./a.out’.
Program terminated with signal 11, Segmentation fault.
#0  0×08048524 in dummy_function () at d.c:4
4               *ptr = 0×00;

哇,好历害,还是一步就定位到了错误所在地,佩服一下Linux/Unix系统的此类设计。
接着考虑下去,以前用windows系统下的ie的时侯,有时打开某些网页,会出现“运行时错误”,这个时侯如果恰好你的机器上又装有windows的编译器的话,他会弹出来一个对话框,问你是否进行调试,如果你选择是,编译器将被打开,并进入调试状态,开始调试。
Linux下如何做到这些呢?我的大脑飞速地旋转着,有了,让它在SIGSEGV的handler中调用gdb,于是第三个方法又诞生了:
3.段错误时启动调试:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>

void dump(int signo)
{
char buf[1024];
char cmd[1024];
FILE *fh;

snprintf(buf, sizeof(buf), “/proc/%d/cmdline”, getpid());
if(!(fh = fopen(buf, “r”)))
exit(0);
if(!fgets(buf, sizeof(buf), fh))
exit(0);
fclose(fh);
if(buf[strlen(buf) - 1] == ‘\n’)
buf[strlen(buf) - 1] = ‘\0′;
snprintf(cmd, sizeof(cmd), “gdb %s %d”, buf, getpid());
system(cmd);

exit(0);
}

void
dummy_function (void)
{
unsigned char *ptr = 0×00;
*ptr = 0×00;
}

int
main (void)
{
signal(SIGSEGV, &dump);
dummy_function ();

return 0;
}

编译运行效果如下:

xiaosuo@gentux test $ gcc -g -rdynamic f.c
xiaosuo@gentux test $ ./a.out
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB.  Type “show warranty” for details.
This GDB was configured as “i686-pc-linux-gnu”…Using host libthread_db library “/lib/libthread_db.so.1″.

Attaching to program: /home/xiaosuo/test/a.out, process 9563
Reading symbols from /lib/libc.so.6…done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2…done.
Loaded symbols for /lib/ld-linux.so.2
0xffffe410 in __kernel_vsyscall ()
(gdb) bt
#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb7ee4b53 in waitpid () from /lib/libc.so.6
#2  0xb7e925c9 in strtold_l () from /lib/libc.so.6
#3  0×08048830 in dump (signo=11) at f.c:22
#4  <signal handler called>
#5  0x0804884c in dummy_function () at f.c:31
#6  0×08048886 in main () at f.c:38

怎么样?是不是依旧很酷?
以上方法都是在系统上有gdb的前提下进行的,如果没有呢?其实glibc为我们提供了此类能够dump栈内容的函数簇,详见/usr/include/execinfo.h(这些函数都没有提供man page,难怪我们找不到),另外你也可以通过gnu的手册进行学习。
4.利用backtrace和objdump进行分析:
重写的代码如下:

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

/* A dummy function to make the backtrace more interesting. */
void
dummy_function (void)
{
unsigned char *ptr = 0×00;
*ptr = 0×00;
}

void dump(int signo)
{
void *array[10];
size_t size;
char **strings;
size_t i;

size = backtrace (array, 10);
strings = backtrace_symbols (array, size);

printf (“Obtained %zd stack frames.\n”, size);

for (i = 0; i < size; i++)
printf (“%s\n”, strings[i]);

free (strings);

exit(0);
}

int
main (void)
{
signal(SIGSEGV, &dump);
dummy_function ();

return 0;
}

编译运行结果如下:

xiaosuo@gentux test $ gcc -g -rdynamic g.c
xiaosuo@gentux test $ ./a.out
Obtained 5 stack frames.
./a.out(dump+0×19) [0x80486c2]
[0xffffe420]
./a.out(main+0×35) [0x804876f]
/lib/libc.so.6(__libc_start_main+0xe6) [0xb7e02866]
./a.out [0x8048601]

这次你可能有些失望,似乎没能给出足够的信息来标示错误,不急,先看看能分析出来什么吧,用objdump反汇编程序,找到地址0x804876f对应的代码位置:

xiaosuo@gentux test $ objdump -d a.out
8048765:       e8 02 fe ff ff          call   804856c <signal@plt>
804876a:       e8 25 ff ff ff          call   8048694 <dummy_function>
804876f:       b8 00 00 00 00          mov    $0×0,%eax
8048774:       c9                      leave

我们还是找到了在哪个函数(dummy_function)中出错的,信息已然不是很完整,不过有总比没有好的啊!
后记:
本文给出了分析”段错误”的几种方法,不要认为这是与孔乙己先生的”回”字四种写法一样的哦,因为每种方法都有其自身的适用范围和适用环境,请酌情使用,或遵医嘱。

对于段错误这种问题。可以分析以下原因:
(1):指针非法,比如使用没有初始化的指针(没有为此指针指向的对象分配空间),或着Free掉之后再次使用。
(2):数组访问越界,访问的元素下标超过数组围长
(3):缓存溢出,对于这种while(1) {do}的程序,这个问题最容易发生,多此sprintf或着strcat有可能将某个
buff填满,溢出,所以每次使用前,最好memset一下,不过要是一开始就是段错误,而不是运行了一会儿出现的,(3)的可能性就比较小。

无觅相关文章插件

Popularity: 13%

分类: C++, linux 标签: