Ⅰ linux 设置堆栈大小 为无限制
你好。
执行命令ulimit -a,查看栈大小的限制。
通过使用 ulimit -s 数字 进行设置。
Ⅱ linux堆栈地址错误与报错函数偏移怎么算
一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的。
在glibc头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈。
[cpp] view plain print?
int backtrace(void **buffer,int size)
该函数用于获取当前线程的调用堆栈,获取的信息将会被存放在buffer中,它是一个指针列表。参数 size 用来指定buffer中可以保存多少个void* 元素。函数返回值是实际获取的指针个数,最大不超过size大小
在buffer中的指针实际是从堆栈中获取的返回地址,每一个堆栈框架有一个返回地址
注意:某些编译器的优化选项对获取正确的调用堆栈有干扰,另外内联函数没有堆栈框架;删除框架指针也会导致无法正确解析堆栈内容
[cpp] view plain print?
char ** backtrace_symbols (void *const *buffer, int size)
backtrace_symbols将从backtrace函数获取的信息转化为一个字符串数组. 参数buffer应该是从backtrace函数获取的指针数组,size是该数组中的元素个数(backtrace的返回值)
函数返回值是一个指向字符串数组的指针,它的大小同buffer相同.每个字符串包含了一个相对于buffer中对应元素的可打印信息.它包括函数名,函数的偏移地址,和实际的返回地址
现在,只有使用ELF二进制格式的程序才能获取函数名称和偏移地址.在其他系统,只有16进制的返回地址能被获取.另外,你可能需要传递相应的符号给链接器,以能支持函数名功能(比如,在使用GNU ld链接器的系统中,你需要传递(-rdynamic), -rdynamic可用来通知链接器将所有符号添加到动态符号表中,如果你的链接器支持-rdynamic的话,建议将其加上!)
该函数的返回值是通过malloc函数申请的空间,因此调用者必须使用free函数来释放指针.
注意:如果不能为字符串获取足够的空间函数的返回值将会为NULL
[cpp] view plain print?
void backtrace_symbols_fd (void *const *buffer, int size, int fd)
backtrace_symbols_fd与backtrace_symbols 函数具有相同的功能,不同的是它不会给调用者返回字符串数组,而是将结果写入文件描述符为fd的文件中,每个函数对应一行.它不需要调用malloc函数,因此适用于有可能调用该函数会失败的情况
下面是glibc中的实例(稍有修改):
[cpp] view plain print?
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
/* Obtain a backtrace and print it to @code{stdout}. */
void print_trace (void)
{
void *array[10];
size_t size;
char **strings;
size_t i;
size = backtrace (array, 10);
strings = backtrace_symbols (array, size);
if (NULL == strings)
{
perror("backtrace_synbols");
Exit(EXIT_FAILURE);
}
printf ("Obtained %zd stack frames.\n", size);
for (i = 0; i < size; i++)
printf ("%s\n", strings[i]);
free (strings);
strings = NULL;
}
/* A mmy function to make the backtrace more interesting. */
void mmy_function (void)
{
print_trace ();
}
int main (int argc, char *argv[])
{
mmy_function ();
return 0;
}
输出如下:
[cpp] view plain print?
Obtained 4 stack frames.
./execinfo() [0x80484dd]
./execinfo() [0x8048549]
./execinfo() [0x8048556]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x70a113]
我们还可以利用这backtrace来定位段错误位置。
通常情况系,程序发生段错误时系统会发送SIGSEGV信号给程序,缺省处理是退出函数。我们可以使用 signal(SIGSEGV, &your_function);函数来接管SIGSEGV信号的处理,程序在发生段错误后,自动调用我们准备好的函数,从而在那个函数里来获取当前函数调用栈。
举例如下:
[cpp] view plain print?
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <execinfo.h>
#include <signal.h>
void mp(int signo)
{
void *buffer[30] = {0};
size_t size;
char **strings = NULL;
size_t i = 0;
size = backtrace(buffer, 30);
fprintf(stdout, "Obtained %zd stack frames.nm\n", size);
strings = backtrace_symbols(buffer, size);
if (strings == NULL)
{
perror("backtrace_symbols.");
exit(EXIT_FAILURE);
}
for (i = 0; i < size; i++)
{
fprintf(stdout, "%s\n", strings[i]);
}
free(strings);
strings = NULL;
exit(0);
}
void func_c()
{
*((volatile char *)0x0) = 0x9999;
}
void func_b()
{
func_c();
}
void func_a()
{
func_b();
}
int main(int argc, const char *argv[])
{
if (signal(SIGSEGV, mp) == SIG_ERR)
perror("can't catch SIGSEGV");
func_a();
return 0;
}
编译程序:
gcc -g -rdynamic test.c -o test; ./test
输出如下:
[cpp] view plain print?
Obtained6stackframes.nm
./backstrace_debug(mp+0x45)[0x80487c9]
[0x468400]
./backstrace_debug(func_b+0x8)[0x804888c]
./backstrace_debug(func_a+0x8)[0x8048896]
./backstrace_debug(main+0x33)[0x80488cb]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x129113]
(这里有个疑问: 多次运行的结果是/lib/i368-Linux-gnu/libc.so.6和[0x468400]的返回地址是变化的,但不变的是后三位, 不知道为什么)
接着:
objmp -d test > test.s
在test.s中搜索804888c如下:
[cpp] view plain print?
8048884 <func_b>:
8048884: 55 push %ebp
8048885: 89 e5 mov %esp, %ebp
8048887: e8 eb ff ff ff call 8048877 <func_c>
804888c: 5d pop %ebp
804888d: c3 ret
其中80488c时调用(call 8048877)C函数后的地址,虽然并没有直接定位到C函数,通过汇编代码, 基本可以推出是C函数出问题了(pop指令不会导致段错误的)。
我们也可以通过addr2line来查看
[cpp] view plain print?
addr2line 0x804888c -e backstrace_debug -f
输出:
[cpp] view plain print?
func_b
/home/astrol/c/backstrace_debug.c:57
以下是简单的backtrace原理实现:
Ⅲ linux的常用命令及技巧
一。 通用命令:
1. date :print or set the system date and time2. stty -a: 可以查看或者打印控制字符(Ctrl-C, Ctrl-D, Ctrl-Z等)3. passwd: print or set the system date and time (用passwd -h查看)4. logout, login: 登录shell的登录和注销命令5. pwd: print or set the system date and time6. more, less, head tail: 显示或部分显示文件内容.7. lp/lpstat/cancel, lpr/lpq/lprm: 打印文件.8. 更改文件权限: chmod u+x...9. 删除非空目录:rm -fr dir10.拷贝目录: cp -R dir11. fg jobid :可以将一个后台进程放到前台。Ctrl-z 可以将前台进程挂起(suspend), 然后可以用bg jobid 让其到后台运行。job & 可以直接让job直接在后台运行。12. kill 的作用: send a signal to a process. eg: kill -9 发送的是SIG_KILL信号。。。 具体发送什么信号 可以通过 man kill 查看。13. ps 的用法, ps -e 或 ps -o pid,ppid,session,tpgid, comm (其中session显示的sessionid, tpgid显示前台进程组id, comm显示命令名称。)二 .ubuntu常用命令:
1. dpkg: package manager for Debian* 安装: dpkg -i package* 卸载: dpkg -r package* 卸载并删除配置文件: dpkg -P |--purge package* 如果安装一个包时。说依赖某些库。 可以先 apt-get install somelib...* 查看软件包安装内容 :dpkg -L package* 查看文件由哪个软件包提供: dpkg -S filename* 另外 dpkg还有 dselect和aptitude 两个frontend.2. apt* 安装: apt-get install packs* apt-get update : 更新源* apt-get upgrade: 升级系统。* apt-get dist-upgrade: 智能升级。安装新软件包,删除废弃的软件包* apt-get -f install : -f == --fix broken 修复依赖* apt-get autoremove: 自动删除无用的软件* apt-get remove packages :删除软件* apt-get remove package --purge 删除包并清除配置文件* 清除所以删除包的残余配置文件: dpkg -l |grep ^rc|awk '{print $2}' |tr [/n] [ ]|sudo xargs dpkg -P* 安装软件时候包的临时存放目录 : /var/cache/apt/archives* 清除该目录: apt-get clean* 清除该目录的旧版本的软件缓存: apt-get autoclean* 查询软件some的依赖包: apt-cache depends some* 查询软件some被哪些包依赖: apt-get rdepends some* 搜索软件: apt-cache search name|regexp* 查看软件包的作用:apt-cache show package* 查看一个软件的编译依赖库: apt-cache showsrc packagename|grep Build-Depends* 下载软件的源代码 : apt-get source packagename (注: sources.list 中应该有 deb-src 源)* 安装软件包源码的同时, 安装其编译环境 :apt-get build-dep packagename (有deb-src源)* 如何将本地光盘加入安装源列表: apt-cdrom add3. 系统命令:* 查看内核版本: uname -a* 查看ubuntu 版本: cat /etc/issue* 查看网卡状态 : ethtool eth0* 查看内存,cpu的信息: cat /proc/meminfo ; cat /proc/cpuinfo(/proc下面的有很多系统信息)* 打印文件系统空间使用情况: df -h* 查看硬盘分区情况: fdisk -l* 产看文件大小: -h filename;* 查看目录大小: -hs dirname ; -h dirname是查看目录下所有文件的大小* 查看内存的使用: free -m|-g|-k* 查看进程: ps -e 或ps -aux -->显示用户* 杀掉进程: kill pid* 强制杀掉: killall -9 processname4. 网络相关: * 配置 ADSL: sudo pppoeconf* ADSL手工拨号: sudo pon dsl-provider* 激活 ADSL : sudo /etc/ppp/pppoe_on_boot* 断开 ADSL: sudo poff* 根据IP查网卡地址: arping IP地址* 产看本地网络信息(包括ip等): ifconfig | ifconfig eth0* 查看路由信息: netstat -r* 关闭网卡: sudo ifconfig eth0 down* 启用网卡: sudo ifconfig eth0 up* 添加一个服务: sudo update-rc.d 服务名 defaults 99* 删除一个服务: sudo update-rc.d 服务名 remove* 临时重启一个服务: /etc/init.d/服务名 restart* 临时关闭一个服务: /etc/init.d/服务名 stop* 临时启动一个服务: /etc/init.d/服务名 start* 控制台下显示中文: sudo apt-get install zhcon* 查找某个文件: whereis filename 或 find 目录 -name 文件名*通过ssh传输文件scp -rp /path/filename username@remoteIP:/path #将本地文件拷贝到服务器上scp -rp username@remoteIP:/path/filename /path #将远程文件从服务器下载到本地5. 压缩:*解压缩 a.tar.gz: tar zxvf a.tar.gz*解压缩 a.tar.bz2: tar jxvf a.tar.bz2*压缩aaa bbb目录为xxx.tar.gz: tar zcvf xxx.tar.gz aaa bbb*压缩aaa bbb目录为xxx.tar.bz2: tar jcvf xxx.tar.bz2 aaa bbb
6. Nautilus:特殊 URI 地址* computer:/// - 全部挂载的设备和网络* network:/// - 浏览可用的网络* burn:/// - 一个刻录 CDs/DVDs 的数据虚拟目录* smb:/// - 可用的 windows/samba 网络资源* x-nautilus-desktop:/// - 桌面项目和图标* file:/// - 本地文件* trash:/// - 本地回收站目录* ftp:// - FTP 文件夹* ssh:// - SSH 文件夹* fonts:/// - 字体文件夹,可将字体文件拖到此处以完成安装* themes:/// - 系统主题文件夹* 显示隐藏文件: Ctrl+h* 显示地址栏: Ctrl+l* 查看已安装字体: 在nautilus的地址栏里输入”fonts:///“,就可以查看本机所有的fonts
7.补充部分:
* 查看本地所有的tpc,udp监听端口: netstat -tupln (t=tcp, u=udp, p=program, l=listen, n=numric)* 通过man搜说相关命令: man -k keyword . eg: man -k user* 或者用 apropos* 统计文件所占用的实际磁盘空间: ( - estimate file space usage)* 统计文件中的字符,字节数: wc -c/-l/-w (wc - print the number of newlines, words, and bytes in files)* 查看文件的内容: od -x/-c/.... (od - mp files in octal and other formats)我认为od最有用的就是文件的字节流了: od -t x1 filename查看文件的 Ascii 码形式: od -t c filename (其中统计信息最左边的是: 字节数)* 查找命令所在文件的位置: which od 输出: /usr/bin/od查看该文件由哪个包提供: dpkg -S /usr/bin/od 输出: coreutils: /usr/bin/od再查看coreutils包的全部内容就知道了linux的核心命令: dpkg -L coreutils然后 info coreutils 哈哈,认真学吧, 满世界都是命令!* 可以用man 命令产看某个命令的所有section 的解释: man -a tty然后用q,和next 转换到下一个section的解释* bash 的好用的快捷键:ctrl+a:光标移到行首。ctrl+b:光标左移一个字母ctrl+c:杀死当前进程。ctrl+d:退出当前 Shell。ctrl+e:光标移到行尾。ctrl+h:删除光标前一个字符,同 backspace 键相同。ctrl+k:清除光标后至行尾的内容。ctrl+l:清屏,相当于clear。ctrl+r:搜索之前打过的命令。会有一个提示,根据你输入的关键字进行搜索bash的historyctrl+u: 清除光标前至行首间的所有内容。ctrl+w: 移除光标前的一个单词ctrl+t: 交换光标位置前的两个字符ctrl+y: 粘贴或者恢复上次的删除ctrl+d: 删除光标所在字母;注意和backspace以及ctrl+h的区别,这2个是删除光标前的字符ctrl+f: 光标右移ctrl+z : 把当前进程转到后台运行,使用’ fg ‘命令恢复。比如top -d1 然后ctrl+z ,到后台,然后fg,重新恢复* 快速粘贴:先在一个地方选中文字,在欲粘贴的地方按鼠标 中键 即可。* 等效中键:a 、按下滑轮等效于中键。b、同时按下鼠标 左右键,等效于中键。* 快速重启X服务: 同时按下: Alt + Ctrl + Backspace 三个键。* 打开运行窗口: 同时按下 Alt + F2 键。* 戴屏: a、全屏:直接按下 PrtScr 键。b、当前窗口:同时按下 Alt + PrtScr 键。c、延时戴屏:在 终端 或 运行窗口中输入命令: gnome-screenshot --delay 3 ,将延时 3 秒后戴屏。* 直接将 文件管理器 中的文件拖到 GNOME终端 中就可以在终端中得到完整的路径名。 8.ulimitulimit:显示(或设置)用户可以使用的资源的限制(limit),这限制分为软限制(当前限制)和硬限制(上限),其中硬限制是软限制的上限值,应用程序在运行过程中使用的系统资源不超过相应的软限制,任何的超越都导致进程的终止。ulimited 不限制用户可以使用的资源,但本设置对可打开的最大文件数(max open files)和可同时运行的最大进程数(max user processes)无效-a 列出所有当前资源极限-c 设置core文件的最大值.单位:blocks-d 设置一个进程的数据段的最大值.单位:kbytes-f Shell 创建文件的文件大小的最大值,单位:blocks-h 指定设置某个给定资源的硬极限。如果用户拥有 root 用户权限,可以增大硬极限。任何用户均可减少硬极限-l 可以锁住的物理内存的最大值-m 可以使用的常驻内存的最大值,单位:kbytes-n 每个进程可以同时打开的最大文件数-p 设置管道的最大值,单位为block,1block=512bytes-s 指定堆栈的最大值:单位:kbytes-S 指定为给定的资源设置软极限。软极限可增大到硬极限的值。如果 -H 和 -S 标志均未指定,极限适用于以上二者-t 指定每个进程所使用的秒数,单位:seconds-u 可以运行的最大并发进程数-v Shell可使用的最大的虚拟内存,单位:kbyteseg: ulimit -c 1000(可以先通过ulimit -c 查看原来的值)
Ⅳ 求教关于linux的堆栈设置
在/etc/profile 的最后面添加ulimit -s unlimited 保存,source /etc/profile使修改文件生效
linux查看修改线程默认栈空间大小 :ulimit -s
1、通过命令 ulimit -s 查看linux的默认栈空间大小,默认情况下 为10240 即10M
2、通过命令 ulimit -s 设置大小值 临时改变栈空间大小:ulimit -s 102400, 即修改为100M
3、可以在/etc/rc.local 内 加入 ulimit -s 102400 则可以开机就设置栈空间大小
4、在/etc/security/limits.conf 中也可以改变栈空间大小:
#<domain> <type> <item> <value>
* soft stack 102400
重新登录,执行ulimit -s 即可看到改为102400 即100M
Ⅳ linux上多线程程序崩溃使用什么方法可以记录堆栈
gcc编译时加-g参数,然后用gdb去跑,挂掉的时候使用bt命令就可以看到某一线程的调用栈了,你可以使用thread命令去切换线程,就可以看到不同线程的调用栈了,具体去网络一下gdb的用法就行了。 另: 还可以把堆栈错误给mp core,如果你觉得有必...
Ⅵ Redhat Linux中怎样自动设置线程堆栈大小
不是可以直接用线程属性进行设置吗?
我写了一个小程序。如下:
#include <pthread.h>
#include <limits.h>#define Thread_NUM 5void *MultiThread_soap_serve(){ sleep(5); printf("new pthread!!\n");}//PTHREAD_STACK_MIN 经过计算是16K。//64*16K = 1M,线程堆栈应该是够用的。#define MICHAEL_SET_PTHREAD_STACK_SIZE 64int main(){ pthread_attr_t attr; pthread_attr_init(&attr); size_t stacksize = MICHAEL_SET_PTHREAD_STACK_SIZE*PTHREAD_STACK_MIN; //stacksize =PTHREAD_STACK_MIN; //stackaddr=(void*)malloc((N+1)*PTHREAD_STACK_MIN); //pthread_attr_getstack(&attr,&statckattr,&stacksize); //pthread_attr_setstack(&attr,stackaddr,); pthread_attr_setstacksize(&attr,stacksize); int iThreadNum = 0; pthread_t PSoapThread[Thread_NUM]; for ( ; iThreadNum < Thread_NUM ; iThreadNum++ ) { pthread_create(&PSoapThread[iThreadNum],&attr,MultiThread_soap_serve,(void *)NULL); } pthread_attr_destroy(&attr); while(1) { sleep(10); printf("main!!\n"); }}
Ⅶ Linux/Unix下程序的堆栈大小是怎么定的
在/etc/profile 的最后面添加ulimit -s unlimited 保存,source /etc/profile使修改文件生效 linux查看修改线程默认栈空间大小 :ulimit -s 1、通过命令 ulimit -s 查看linux的默认栈空间大小,默认情况下 为10240 即10M
Ⅷ linux 怎么查看segmentation fault堆栈
gdb ExeName
(gdb)core core.xx
(gdb)bt
core mp 一般是在segmentation fault(段错误)的情况下产生的文件,需要通过ulimit来设置才会得到的。关于Linux命令的介绍,看看《linux就该这么学》,具体关于这一章地址3w(dot)linuxprobe/chapter-02(dot)html.
Ⅸ Redhat linux常用的命令有哪些
<1>ls:列目录。
用法:ls或ls
dirName,参数:-a显示所有文件,-l详悉列出文件。
<2>mkdir:建目录。
用法:mkdir
dirName,参数:-p建多级目录,如:mkdir
a/b/c/d/e/f
-p
<3>mount:挂载分区或镜像文件(.iso,.img)文件。
用法:
a.磁盘分区:mount
deviceName
mountPoint
-o
options,其中deviceName是磁盘分区的设备名,比如/dev/hda1,/dev/cdrom,/dev/fd0,mountPoint是挂载点,它是一个目录,options是参数,如果分区是linux分区,一般不用-o
options,如果是windows分区那options可以是iocharset=cp936,这样windows分区里的中文文件名就能显示出来了。用例:比如/dev/hda5是linux分区,我要把它挂到目录a上(如没目录a那就先mkdir
a),mount
/dev/hda5
a,这样目录a里的东西就是分区hda5里的东西了,比如hda1是windows分区,要把它挂到b上,mount
/dev/hda1
b
-o
iocharset=cp936。
b.镜像文件:mount
fileName
mountPoint
-o
loop,fileName是镜像文件名(*.iso,*.img),其它的不用说了,跟上面一样。用例:如我有一个a.iso光盘镜像文件,mount
a.iso
a
-o
loop,这样进入目录a你就能浏览a.iso的内容了,*.img文件的用法一样。
<4>find:查找文件。
用法:find
inDir
-name
filename,inDir是你要在哪个目录找,filename是你要找的文件名(可以用通配符),用通配符时filename做好用单引号引起来,否则有时会出错,用例:find
.
-name
test*,在当前目录查找以test开头的文件。
<5>grep:在文件里查找指定的字符串。
用法:grep
string
filename,在filename(可用通配符)里查找string(最好用双引号引起来)。参数:-r在所有子目录里的filename里找。用例:grep
hello
*.c
-r在当前目录下(包括子目录)的所有.c文件里查找hello。
<5>vi:编辑器。不用说,用linux的话,这个东西一定要会用。
用法:(只能简单说一下),vi
filename。filename就是你要编辑的文本文件。用了执行vi
filename后,你可能会发现你无法编辑文本内容,不要着急,这是因为vi还没进入编辑状态,按a或i就可以进入编辑状态了,进入编辑状态后你就可以编辑文本了。要退出编辑状态按Esc键就可以了。以下操作均要在非编辑状态下。查找文本:输入/和你要查找的文本并回车。退出:
输入:
和q并回车,如果你修改了文本,那么你要用:q!回车才能退出。保存:输入:
w回车,如果是只读文件要用:
w!。保存退出:输入:
wq回车,如果是只读就:
wq!回车。取消:
按u就可以了,按一次就取消一步,可按多次取消多步。复制粘贴一行文本:把光标移到要复制的行上的任何地方,按yy(就是连按两次y),把光标移到要粘贴地方的上一行,按p,刚才那行文本就会被插入到光标所在行的下一行,原来光标所在行后面所有行会自动下移一行。复制粘贴多行文本:跟复制一行差不多,只是yy改成先输入要复制的行数紧接着按yy,后面的操作一样。把光标移到指定行:输入:和行号并回车,比如移到123行:123回车,移到结尾回车。
Ⅹ linux上程序溢出了 怎么查看堆栈
我晕, 你到底是在什么发行版? 从提示上来看,要用 apt-get install 来装,说明是 ubuntu/debian之类的linux发行版,你怎么又会去用 rpm 来查询和安装? 你不说你是什么发行版,楼上回答的人也不管,直接就让你用rpm,误人子弟啊。正确的方法是,sudo apt-get install build-essential这个才是你的系统应该用的,装好后命令行下运行gcc -v就会打印出你使用gcc的版本信息了,然后就可以用了,比如gcc -o test test.c就会编译test.c,生成可执行文件 test然后./test就会运行test 我再晕,楼主,提示你没有test.c,你的C源文件呢?我这里是用test.c做例子,你的源文件叫什么名字,你就把test.c换成你的文件的名字啊。另外,你要把你的源文件先保存在linux机器上,比方说放到了 /home/yourname/aaa那你要先cd /home/yourname/aaa然后再gcc -o test test.c