精华内容
下载资源
问答
  • linux抓取堆栈信息

    千次阅读 2012-06-02 21:06:38
    方法1 :pstack pid 内部原理和 方法2相同,pstack 为 方法2的一个 脚本,信息没有比方法2 ...通过gdb命令获取所有当前,线程堆栈信息,此方法会阻塞进程的当前运行,退出gdb 进程继续运行。 方法3:gcore -p pid
     
    

    方法1 :pstack pid

    内部原理和 方法2相同,pstack 为 方法2的一个 脚本,信息没有比方法2 详细,但阻塞程序时间很短,几乎可以考虑不受影响。

    方法2:gdb -p pid

    thread apply all bt

    通过gdb命令获取所有当前,线程堆栈信息,此方法会阻塞进程的当前运行,退出gdb 进程继续运行。

    方法3:gcore -p pid

    获取运行进程的当前的core文件,然后通过gdb 分析core文件。

    内部使用gdb 命令 generate-core-file 生成core文件



    早上发现一个进程没有相应, 试图gdb之.

    (gdb) attach 30721
    Attaching to program: /data0/s/bin/s, process 30721
    ptrace: Operation not permitted.

    晕倒, 俺已经是sudo权限了. 后来看到一篇博客说:当他已经在 gdb 某个进程时, 试图再利用 gcore 来手动产生一个 core 文件而不得(可以在gdb下用 generate-core-file 完成), 我有所启发, 莫非还有别人在gdb 这个进程.

    ps 一下, 发现我的猜想是对的, 我进一步猜想, strace 也应该会失败.

    0> strace -p 30721
    attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted

    果然如此, 两者都用到了 ptrace 这个系统调用. man ptrace 可以查看详情:

    The ptrace system call provides a means by which a parent process may observe and control the execution of another pro-cess, and examine and change its core image and registers. It is primarily used to implement breakpoint debugging and system call tracing.

    看linux内核详解的话, 应该能给出更深层次的解释, 我现在还留在意会阶段.


    展开全文
  • 当服务器内存飙升或者cpu负载飙升的时候,可以使用如下步骤排查问题:1、终端输入top命令,键盘大写的情况下按P(cpu负载率从高到低排序)或者M(内存使用率从高到低排序),可以查看导致cpu或者内存飙升的java pid。...

    当服务器内存飙升或者cpu负载飙升的时候,可以使用如下步骤排查问题:

    1、终端输入top命令,键盘大写的情况下按P(cpu负载率从高到低排序)或者M(内存使用率从高到低排序),可以查看导致cpu或者内存飙升的java pid。

    57f70456c728010478b5d8884db0e6cb.png

    2、jstack PID号 > jstack.log

    上面的命令可以保存当前时刻的线程栈到 jstack.log 文件中(保存在当前路径下)

    3、分析栈文件

    3.1 grep 'java.lang.Thread.State' jstack.log  | wc -l

    上述命令可以统计java.lang.Thread.State出现的次数

    3e1f6fc005c41b7ad932661678946a95.png

    3.2  grep -A 1 'java.lang.Thread.State' jstack.log  | grep -v 'java.lang.Thread.State' | sort | uniq -c |sort -n

    该命令可以将线程栈文件的状态按次数排序显示

    8ee7eced809dd6114ce35b7d9dbeec1b.png

    4、jmap -dump:format=b,file=heap.log pid

    上述命令可以保存当前的堆情况到heap.log文件中。

    5、将heap.log传输到windows系统下,复制一份,后缀改成.hprof

    下载Eclipse的内存分析工具,地址:https://www.eclipse.org/mat/downloads.php

    2af83cd8086ea08febd971a49e686649.png

    下载完成后,双击MemoryAnalyzer.exe,点击Open a Heap Dump

    40e030dc7422afb333ecd32d3145ca3e.png

    选择桌面上的堆文件,点击打开:

    1af862c63cbff6df0dd69a954ca834b7.png

    选择第一个内存分析报告,然后点Finish:

    e18011c12bc7c3d299b4aae5254c8be7.png

    就会打开一个总体情况页面:

    49d34b3542bc21847f0dcd116edf70c8.png

    点击左下角的Table Of Contents,里面有多种分析供选择:

    2c2e1251a80652c7866bb7f7d2094f03.png

    每一个选项几乎都有直观的饼状图显示对象的占用情况:

    81517ec2e37a77ce30c49a29c23803f3.png

    当然也有线程的堆使用情况分析,可以方便地找到占用大量内存的线程,找到真正导致内存、cpu飙升的罪魁祸首!

    cb8cc558b1f5377c064145a2a94cca22.png

    展开全文
  • linux c++获取堆栈信息

    千次阅读 2014-11-18 10:07:18
    以下来自muduo的代码: #ifndef MUDUO_BASE_EXCEPTION_H #define MUDUO_BASE_EXCEPTION_H #include #include namespace muduo { ...class Exception : public std::exception ... explicit Exception(const char

    以下来自muduo的代码:

    #ifndef MUDUO_BASE_EXCEPTION_H
    #define MUDUO_BASE_EXCEPTION_H
    
    #include <muduo/base/Types.h>
    #include <exception>
    
    namespace muduo
    {
    
    class Exception : public std::exception
    {
     public:
      explicit Exception(const char* what);
      explicit Exception(const string& what);
      virtual ~Exception() throw();
      virtual const char* what() const throw();
      const char* stackTrace() const throw();
    
     private:
      void fillStackTrace();
    
      string message_;
      string stack_;
    };
    
    }
    
    #endif

    #include <muduo/base/Exception.h>
    
    //#include <cxxabi.h>
    #include <execinfo.h>
    #include <stdlib.h>
    
    using namespace muduo;
    
    Exception::Exception(const char* msg)
      : message_(msg)
    {
      fillStackTrace();
    }
    
    Exception::Exception(const string& msg)
      : message_(msg)
    {
      fillStackTrace();
    }
    
    Exception::~Exception() throw ()
    {
    }
    
    const char* Exception::what() const throw()
    {
      return message_.c_str();
    }
    
    const char* Exception::stackTrace() const throw()
    {
      return stack_.c_str();
    }
    
    void Exception::fillStackTrace()
    {
      const int len = 200;
      void* buffer[len];
      int nptrs = ::backtrace(buffer, len);
      char** strings = ::backtrace_symbols(buffer, nptrs);
      if (strings)
      {
        for (int i = 0; i < nptrs; ++i)
        {
          // TODO demangle funcion name with abi::__cxa_demangle
          stack_.append(strings[i]);
          stack_.push_back('\n');
        }
        free(strings);
      }
    }
    


    展开全文
  • Linux 打印堆栈方法

    2021-01-06 09:44:10
    linux内核堆栈打印方法 dump_stack() 或 __backtrace() linux应用层堆栈打印方法 int backtrace(void **buffer, int size); 获取当前的调用栈信息,结果存储在buffer中,返回值为栈的深度,参数size限制栈的最大...
  • 在编写稳定可靠的软件服务时经常用到输出...在Linux有比较简便的函数获取堆栈信息:#include #include #include #include #include void handler(int sig) {void *array[5];size_t size;// get void*'s for all e...

    在编写稳定可靠的软件服务时经常用到输出堆栈信息,以便用户/开发者获取准确的运行信息。常用在日志输出,错误报告,异常检测。

    在Linux有比较简便的函数获取堆栈信息:

    #include

    #include

    #include

    #include

    #include

    void handler(int sig) {

    void *array[5];

    size_t size;

    // get void*'s for all entries on the stack

    size = backtrace(array,5);

    // print out all the frames to stderr

    fprintf(stderr,"Error: signal %d:\n",sig);

    char** msgs = backtrace_symbols(array,size);

    for(int i=1;i

    printf("[%d] %s\n",i,msgs[i]);

    exit(1);

    }

    void baz() {

    int *foo = (int*)-1; // make a bad pointer

    printf("%d\n",*foo); // causes segfault

    }

    void bar() { baz(); }

    void foo() { bar(); }

    int main(int argc,char **argv) {

    signal(SIGSEGV,handler); // install our handler

    foo(); // this will call foo,bar,and baz. baz segfaults.

    }

    以上代码从参考的stackoverflow中稍作修改而来。核心就是backtrace与backtrace_symbols两个函数。

    Windows下推荐用StackWalker这个开源代码,支持X86,AMD64,IA64。

    如果你需要一个最简的代码,那么下面是我抽取出来的代码,明显比Linux要复杂一些。(Win的很多功能实现起来要复杂一些,当然也有很多功能实现要比Linux简单很多。)

    我会做一些讲解,在后面。

    #include "stdafx.h"

    #include

    #include

    #include

    #include

    using namespace std;

    HANDLE ph;

    void baz()

    {

    int* v = 0;

    *v = 0;

    }

    void bar()

    {

    baz();

    }

    void foo(){

    __try {

    bar();

    }

    __except(EXCEPTION_EXECUTE_HANDLER) {

    auto sire = SymInitialize(ph,FALSE);

    sire = SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_FAIL_CRITICAL_ERRORS);

    CONTEXT ctx = { 0 };

    ctx.ContextFlags = CONTEXT_FULL;

    RtlCaptureContext(&ctx);

    STACKFRAME64 sf = { 0 };

    #ifdef _M_IX86 // ignore IA64

    auto imageType = IMAGE_FILE_MACHINE_I386;

    sf.AddrPC.Offset = ctx.Eip;

    sf.AddrPC.Mode = AddrModeFlat;

    sf.AddrFrame.Offset = ctx.Ebp;

    sf.AddrFrame.Mode = AddrModeFlat;

    sf.AddrStack.Offset = ctx.Esp;

    sf.AddrStack.Mode = AddrModeFlat;

    #elif _M_X64

    auto imageType = IMAGE_FILE_MACHINE_AMD64;

    sf.AddrPC.Offset = ctx.Rip;

    sf.AddrPC.Mode = AddrModeFlat;

    sf.AddrFrame.Offset = ctx.Rsp;

    sf.AddrFrame.Mode = AddrModeFlat;

    sf.AddrStack.Offset = ctx.Rsp;

    sf.AddrStack.Mode = AddrModeFlat;

    #endif

    MODULEENTRY32 me;

    auto snap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());

    auto info = Module32First(snap,&me);

    while (info) {

    auto dw = SymLoadModule64(ph,me.szExePath,me.szModule,(DWORD64)me.modBaseAddr,me.modBaseSize);

    if (!Module32Next(snap,&me))break;

    }

    CloseHandle(snap);

    auto thread = GetCurrentThread();

    PIMAGEHLP_SYMBOL64 sym = (IMAGEHLP_SYMBOL64 *)malloc(sizeof(IMAGEHLP_SYMBOL64) + 100);

    if (!sym)

    return;

    memset(sym,sizeof(IMAGEHLP_SYMBOL64) + 100);

    sym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);

    sym->MaxNameLength = 100;

    IMAGEHLP_LINE64 line = { 0 };

    line.SizeOfStruct = sizeof(line);

    for (;;) {

    auto result = StackWalk(imageType,ph,thread,&sf,&ctx,SymFunctionTableAccess64,SymGetModuleBase64,0);

    if (result) {

    DWORD64 offset = 0;

    DWORD offset_for_line = 0;

    CHAR und_fullname[100];

    if (sf.AddrPC.Offset != 0) {

    if (SymGetSymFromAddr64(ph,sf.AddrPC.Offset,&offset,sym)) {

    UnDecorateSymbolName(sym->Name,und_fullname,100,UNDNAME_COMPLETE);

    cout << und_fullname;

    }

    if (SymGetLineFromAddr64(ph,&offset_for_line,&line)) {

    cout << " " << line.FileName << "(" << line.LineNumber << ")";

    }

    cout << endl;

    }

    }

    else

    break;

    }

    SymCleanup(ph);

    }

    }

    int main()

    {

    ph = GetCurrentProcess();

    foo();

    return 0;

    }

    编译请链接dbghelp.lib

    核心就是StackWalk与SymGetSymFromAddr64,SymGetLineFromAddr64。

    StackWalk用于获取下一层堆栈。

    SymGetSymFromAddr64用于获取当前函数名。

    SymGetLineFromAddr64用于获取函数所在文件及行号。

    为了这三个函数正常工作,还要初始化符号相关功能(SymInitialize),取得当前线程描述表(RtlCaptureContext),加载用到的模块(SymLoadModule64)。

    用到了这两个头文件。

    上面代码执行后会在控制台输出堆栈信息。

    这篇在Linux与Windows上获取当前堆栈信息的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程小技巧。

    总结

    如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

    本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

    展开全文
  • 下面小编就为大家带来一篇在Linux与Windows上获取当前堆栈信息的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Linux有比较简便的函数获取堆栈信息: 以上代码从参考的stackoverflow中稍作修改而来。核心就是backtrace与backtrace_symbols两个函数。 Windows下推荐用StackWalker这个开源代码,支持X86,AMD64,IA64。 如...
  • linux内核堆栈

    2019-09-30 23:50:23
    一:进程的堆栈  内核在创建进程的时候,在创建task_struct的同时会为进程创建相应的堆栈。每个进程会有两个栈,一个用户栈,存在于用户空间,一个内核栈,存 在于内核空间。当进程在用户空间运行时,cpu堆栈指针...
  • 访问内存时,您正在访问进程地址空间. 进程地址空间分为页面(x86上通常为4 KB).这些是虚拟页面:它们的内容保存在...如上所述,由于ASLR,如果您在程序中执行此操作并多次运行程序,那么您将获得某些地址的非确定性结果.
  • 在编写稳定可靠的软件服务时经常用到输出堆栈...在Linux有比较简便的函数获取堆栈信息: #include <stdio.h> #include <execinfo.h> #include <signal.h> #include <stdlib.h> #inc...
  • cpu此时自动从tss里面获取到esp0,ss0,并将cs,eip,eflags自动压入栈, 但此时的页目录还未切换,虽然已经进入内核栈空间,但此时经过页映射,物理地址还在 进程空间,linux是怎样实现当中断发生时,不破坏进程空间...
  • 使用堆栈信息排查系统性能问题,多线程程序调优(因为这类问题往往都不会输出日志或日志输出定位代码排查的范围太大),堆栈信息对这类问题定位速度快而精准。 查询堆栈信息全文涉及到的指令 线程状态相关 常见到的...
  • JAVA获取线上堆栈信息

    2020-12-11 17:08:55
    下一步就是获取堆栈信息进行分析; 使用kill -3 PID 获取堆栈信息 获取进程的PID ps -ef|grep java 获取堆栈信息 kill -3 PID 获取文件 1> 如果项目通过Tomcat进行发布(普通的web项目),则对应的堆栈信息会...
  • 近日在做一个嵌入式项目,linux平台,发现应用的程序的内存占用很大,经过同事的一起排查,发现系统的线程使用过多,导致应用程序的内存使用急剧增加。 那么线程使用过多为什么会导致内存的占用增加呢,现在我们一...
  • Linux查看线程的堆栈信息

    万次阅读 2016-01-18 22:49:39
    1、使用top命令,查找pid 2、显示线程,查找线程tid  ps -mp #pid# -o THREAD,tid,time | sort -rn 3、将线程id转化为16进制0xtid ...4、显示线程的堆栈信息  jstack #pid#|grep #0xtid# -A 30
  • Linux Kernel版本为 2.4.18-3)输出结果为:   rlim_cur=8388608,rlim_max=4294967295    说明当前的堆栈空间为 8M,但作为扩展,最大可支持 4G(理论值) 转载于:...
  • linux内核堆栈设置过程

    千次阅读 2014-05-07 18:30:16
    内核在没有开启MMU之前,内核堆栈的设置在arch/arm/boot/
  • 调试工具如GDB,可以查看程序运行时函数调用的堆栈信息,有时候在分析程序时要获得堆栈信息,借助于backtrace是很有帮助的,其原型如下: #include <exec
  • 原文:...该博客文章是在我们之前的博客文章《监视和调整Linux网络堆栈:接收数据》的基础上扩展的,该图表带有一系列图表,旨在帮助读者更清晰地了解Linux网络堆栈的工...
  • linux环境下查看C/C++程序的堆栈信息

    千次阅读 2019-05-08 16:16:06
    经常在Windows上开发的工程师们可能已经习惯了图形化的调试界面,在源代码的编辑框上点击就可以添加断点,在调用堆栈的窗口就可以看到程序运行的堆栈信息,但是在 linux 环境下,面对命令行的天下,我们需要掌握一些...
  • linux 堆栈溢出的问题

    2011-08-16 16:59:47
    unix linux 堆栈 溢出 的 问题
  • Linux内核堆栈实现分析 save_stack_trace

    千次阅读 2014-12-13 10:42:38
    Linux 内核为每个线程分配THREAD_SIZE(16k)的栈空间, 在每个堆栈的顶部放着struct thread_info 结构体,用来保存线程相关信息. 其中有几个重要变量: Preempt_count : 此变量分为四部分 0-7bit :当前进程是否...
  • #include <stdio.h> #include <stdlib.h> int add1(int num) { int ret = 0; int *pTmp = NULL; *pTmp = 1; //对未分配内存空间的指针进行赋值,模拟访问非法内存段错误 ret = num + *pTmp;...}

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 70,567
精华内容 28,226
关键字:

linux获取堆栈信息

linux 订阅