VerySource

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3550|回复: 27

函数调用堆栈查看

[复制链接]

1

主题

2

帖子

3.00

积分

新手上路

Rank: 1

积分
3.00
发表于 2020-1-9 08:40:01 | 显示全部楼层 |阅读模式
怎样在运行时查看函数被哪个函数调用?
回复

使用道具 举报

0

主题

14

帖子

13.00

积分

新手上路

Rank: 1

积分
13.00
发表于 2020-1-9 20:18:01 | 显示全部楼层
调试
回复

使用道具 举报

1

主题

2

帖子

3.00

积分

新手上路

Rank: 1

积分
3.00
 楼主| 发表于 2020-1-19 20:54:02 | 显示全部楼层
补充:不是在调试的状态下,

也就是说,用api得到函数被哪个函数调用
回复

使用道具 举报

0

主题

14

帖子

13.00

积分

新手上路

Rank: 1

积分
13.00
发表于 2020-1-20 10:36:02 | 显示全部楼层
api里面好像没有这个功能吧,其实可以根据需要自己在每个函数中添加这样的功能,包括把信息输出到哪个窗口下。
回复

使用道具 举报

0

主题

3

帖子

3.00

积分

新手上路

Rank: 1

积分
3.00
发表于 2020-4-18 01:30:01 | 显示全部楼层
好象vc++中才可以看吧。。具体的我不知道了哈
回复

使用道具 举报

0

主题

6

帖子

6.00

积分

新手上路

Rank: 1

积分
6.00
发表于 2020-4-20 09:45:01 | 显示全部楼层
一般的有界面的调试工具,都有call stack 这个功能来看调用栈的
回复

使用道具 举报

1

主题

13

帖子

9.00

积分

新手上路

Rank: 1

积分
9.00
发表于 2020-4-20 10:00:01 | 显示全部楼层
在source sight 中选中有个Caller的好像...
回复

使用道具 举报

0

主题

15

帖子

13.00

积分

新手上路

Rank: 1

积分
13.00
发表于 2020-4-28 15:15:01 | 显示全部楼层
有个比较笨的办法

在调用时把调用的信息人工写到文件里
回复

使用道具 举报

0

主题

12

帖子

9.00

积分

新手上路

Rank: 1

积分
9.00
发表于 2020-4-29 08:15:01 | 显示全部楼层
DEBUG 版简单些, 通过 ebp 获取函数栈帧, 可以获得 call stack ...
RELEASE 版的不行, 由于编译优化很多函数都不生成栈帧, 有些无聊的家伙又会用 ebp 干些无聊的事情, 难度皮高 ...
回复

使用道具 举报

0

主题

12

帖子

9.00

积分

新手上路

Rank: 1

积分
9.00
发表于 2020-5-6 22:00:01 | 显示全部楼层
无聊ing  .....

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

int cc = 0;
static void entry();
static void foo1();
static void foo2();
static void foo3();
static void foo4();
static void traceCallStack();

#define FOOBAR( __name__ )                        \
void __name__(){                                        \
        if( ++cc >= 100 )                                \
        {        if( cc%16 == 0 ) traceCallStack();        }                \
        else switch( rand() % 4 ){                \
        case 0:foo1();foo2();break;                \
        case 1:foo2();foo3();break;                \
        case 2:foo3();foo4();break;                \
        case 3:if(!(rand()%4))traceCallStack();break;        \
}}

FOOBAR( foo1 );
FOOBAR( foo2 );
FOOBAR( foo3 );
FOOBAR( foo4 );

struct name_rcd_st {
        void*                        func ;
        const char*                name ;
        int                                brk  ; }
name_rcd[] =
{
        { entry                         , "entry"        , 1                } ,
        { foo1                         , "foo1" } ,
        { foo2                         , "foo2" } ,
        { foo3                         , "foo3" } ,
        { foo4                         , "foo4" } ,
        { traceCallStack , "traceCallStack" } ,
        { NULL , NULL   }
};

int name_rcd_compare( const void* lhs , const void* rhs )
{
        return (int)((struct name_rcd_st*)rhs)->func - (int)((struct name_rcd_st*)lhs)->func;
}

void entry()
{
        foo1();
}

int main()
{
        qsort( name_rcd , sizeof( name_rcd ) / sizeof( name_rcd[0] ) - 1 , sizeof( name_rcd[0] ) , name_rcd_compare );
        entry();
        return 0;
}

/*
-----------------------  <-- EBP
      OLD EBP
-----------------------  
      RET ADDR
-----------------------
*/

#define CURR_FRAME( r )                        __asm mov r , ebp
#define NEXT_FRAME( c , r )                r = ((void**)c)[0]
#define RET_ADDR( c , r )                r = ((void**)c)[1]

void* getFrame( void* curr_frame , void** next_frame_ret )
{
        void *next_frame , *ret_addr;
        if( NULL == curr_frame )
        {
                CURR_FRAME( curr_frame );
        }
        NEXT_FRAME( curr_frame , next_frame );
        RET_ADDR( curr_frame , ret_addr );
        *next_frame_ret = next_frame;
        return ret_addr;
}

struct name_rcd_st*        find_func( void* addr , int * off )
{
        struct name_rcd_st*        r = name_rcd;

        for( ;r->func; ++r )
        {
                if( addr > r->func )
                        break;
        }

        if( !r->func )
                return NULL;

        *off = (int)addr - (int)r->func;
        return r;
}

void traceCallStack()
{
        struct name_rcd_st*                        rcd      ;
        void *curr_frame = NULL , * addr_func;
        int          brk = 0        , off = 0;

        printf( "\n..... traceCallStack begin:\n" );

        while( !brk )
        {
                addr_func = getFrame ( curr_frame , &curr_frame );
                rcd       = find_func( addr_func  , &off );
                if( !rcd )        break;
                brk = rcd->brk;
                printf( "%s + %d \n" , rcd->name , off );
        }

        printf( "........ traceCallStack end ....\n" );
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|CopyRight © 2008-2023|verysource.com ( 京ICP备17048824号-1 )

快速回复 返回顶部 返回列表