mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-30 02:47:56 +08:00
Add stacktrace for fiber cpp lib.
This commit is contained in:
parent
0864514ae4
commit
758dd3852a
@ -7,8 +7,8 @@ ARFL = rv
|
||||
#ARFL = cru
|
||||
RANLIB = ${ENV_RANLIB}
|
||||
|
||||
#JMP_CTX = USE_CONTEXT
|
||||
JMP_CTX = USE_JMP_DEF
|
||||
JMP_CTX = USE_CONTEXT
|
||||
#JMP_CTX = USE_JMP_DEF
|
||||
#JMP_CTX = USE_BOOST_JMP
|
||||
|
||||
CFLAGS = -c -g -W \
|
||||
@ -25,7 +25,7 @@ CFLAGS = -c -g -W \
|
||||
-Wcast-qual \
|
||||
-DUSE_FAST_RING \
|
||||
-O3 \
|
||||
#-DDEBUG_STACK \
|
||||
-DDEBUG_STACK \
|
||||
#-DUSE_VALGRIND \
|
||||
#-DUSE_INLINE_MEMCPY\
|
||||
#-DUSE_FAST_TIME \
|
||||
|
@ -10,7 +10,7 @@ extern "C" {
|
||||
|
||||
typedef struct ACL_FIBER_ATTR {
|
||||
unsigned int oflag;
|
||||
#define ACL_FIBER_ATTR_SHARE_STACK (unsigned) 1 << 0
|
||||
#define ACL_FIBER_ATTR_SHARE_STACK (unsigned) (1 << 0)
|
||||
|
||||
size_t stack_size;
|
||||
} ACL_FIBER_ATTR;
|
||||
@ -64,7 +64,7 @@ typedef struct ACL_FIBER_STACK {
|
||||
size_t size;
|
||||
} ACL_FIBER_STACK;
|
||||
|
||||
FIBER_API ACL_FIBER_STACK *acl_fiber_stacktrace(ACL_FIBER *fiber, size_t max);
|
||||
FIBER_API ACL_FIBER_STACK *acl_fiber_stacktrace(const ACL_FIBER *fiber, size_t max);
|
||||
FIBER_API void acl_fiber_stackfree(ACL_FIBER_STACK *stack);
|
||||
|
||||
/**
|
||||
|
@ -60,9 +60,9 @@ typedef struct FIBER_UNIX {
|
||||
#ifdef DEBUG_STACK
|
||||
#include <libunwind.h>
|
||||
|
||||
ACL_FIBER_STACK *acl_fiber_stacktrace(ACL_FIBER *fiber, size_t max)
|
||||
ACL_FIBER_STACK *acl_fiber_stacktrace(const ACL_FIBER *fiber, size_t max)
|
||||
{
|
||||
FIBER_UNIX *fb = (FIBER_UNIX*) fiber;
|
||||
const FIBER_UNIX *fb = (const FIBER_UNIX*) fiber;
|
||||
unw_cursor_t cursor;
|
||||
unw_word_t off, pc;
|
||||
ACL_FIBER_STACK *stack;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "fiber_cpp_define.hpp"
|
||||
|
||||
struct ACL_FIBER;
|
||||
@ -15,6 +17,17 @@ typedef enum
|
||||
FIBER_EVENT_T_IO_URING, // Linux
|
||||
} fiber_event_t;
|
||||
|
||||
class FIBER_CPP_API fiber_frame
|
||||
{
|
||||
public:
|
||||
fiber_frame(void) : pc(0), off(0) {}
|
||||
~fiber_frame(void) {}
|
||||
|
||||
std::string func;
|
||||
long pc;
|
||||
long off;
|
||||
};
|
||||
|
||||
/**
|
||||
* 协程类定义,纯虚类,需要子类继承并实现纯虚方法
|
||||
*/
|
||||
@ -86,6 +99,7 @@ public:
|
||||
*/
|
||||
void set_errno(int errnum);
|
||||
|
||||
public:
|
||||
/**
|
||||
* 获得本次操作的出错信息
|
||||
* @return {const char*}
|
||||
@ -247,6 +261,15 @@ public:
|
||||
static void fiber_create(void (*fn)(ACL_FIBER*, void*),
|
||||
void* ctx, size_t size);
|
||||
|
||||
/**
|
||||
* 获得指定协程的堆栈
|
||||
* @param fb {const fiber&}
|
||||
* @param out {std::vector<stack_frame>&} 存放结果数据
|
||||
* @param max {size_t} 指定获取栈的最大深度
|
||||
*/
|
||||
static void stacktrace(const fiber& fb, std::vector<fiber_frame>& out,
|
||||
size_t max = 50);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* 虚函数,子类须实现本函数,当通过调用 start 方法启动协程后,本
|
||||
|
@ -299,6 +299,25 @@ void fiber::fiber_create(void (*fn)(ACL_FIBER*, void*), void* ctx, size_t size)
|
||||
acl_fiber_create(fn, (void*) ctx, size);
|
||||
}
|
||||
|
||||
void fiber::stacktrace(const fiber& fb, std::vector<fiber_frame>& out, size_t max)
|
||||
{
|
||||
ACL_FIBER *f = fb.get_fiber();
|
||||
ACL_FIBER_STACK *stack = acl_fiber_stacktrace(f, max);
|
||||
if (stack == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < stack->count; i++) {
|
||||
fiber_frame frame;
|
||||
frame.func = stack->frames[i].func;
|
||||
frame.pc = stack->frames[i].pc;
|
||||
frame.off = stack->frames[i].off;
|
||||
out.push_back(frame);
|
||||
}
|
||||
|
||||
acl_fiber_stackfree(stack);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fiber_timer::fiber_timer(void)
|
||||
|
@ -1,8 +1,7 @@
|
||||
CC = g++
|
||||
|
||||
CFLAGS = -c -g -W -Wall -Wcast-qual -Wcast-align \
|
||||
-Waggregate-return -Wno-long-long \
|
||||
-Wpointer-arith -Werror -Wshadow -O3 \
|
||||
-Wno-long-long -Wpointer-arith -Werror -Wshadow -O3 \
|
||||
-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D_USE_FAST_MACRO
|
||||
|
||||
###########################################################
|
||||
|
6
lib_fiber/samples/fiber_stack2/Makefile
Normal file
6
lib_fiber/samples/fiber_stack2/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# Don't build the sample on MacOS because libunwind don't support it.
|
||||
include ./Makefile.in
|
||||
ifeq ($(findstring Linux, $(UNIXNAME)), Linux)
|
||||
SYSLIB += -lunwind -lunwind-x86_64
|
||||
endif
|
||||
PROG = fiber_stack
|
174
lib_fiber/samples/fiber_stack2/Makefile.in
Normal file
174
lib_fiber/samples/fiber_stack2/Makefile.in
Normal file
@ -0,0 +1,174 @@
|
||||
CC = g++
|
||||
|
||||
CFLAGS = -c -g -W -Wall -Wcast-qual -Wcast-align \
|
||||
-Wno-long-long -Wpointer-arith -Werror -Wshadow -O0 \
|
||||
-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D_USE_FAST_MACRO
|
||||
|
||||
###########################################################
|
||||
#Check system:
|
||||
# Linux, SunOS, Solaris, BSD variants, AIX, HP-UX
|
||||
SYSLIB = -ldl -lpthread -lz
|
||||
CHECKSYSRES = @echo "Unknow system type!";exit 1
|
||||
UNIXNAME = $(shell uname -sm)
|
||||
OSTYPE = $(shell uname -p)
|
||||
RPATH = linux64
|
||||
|
||||
ifeq ($(CC),)
|
||||
CC = g++
|
||||
endif
|
||||
|
||||
OS_ENV=$(shell uname -a)
|
||||
ifeq ($(findstring WSL, $(OS_ENV)), WSL)
|
||||
SYSLIB += -liconv
|
||||
endif
|
||||
|
||||
ifeq ($(findstring ubuntu, $(OS_ENV)), ubuntu)
|
||||
SYSLIB += -liconv
|
||||
endif
|
||||
|
||||
ifeq ($(findstring Alpine, $(shell uname -a)), Alpine)
|
||||
SYSLIB += -lucontext
|
||||
endif
|
||||
|
||||
ifeq ($(findstring g++, $(CC)), g++)
|
||||
GCC_VERSION:=$(shell echo `gcc --version|grep ^gcc|cut -d' ' -f3`)
|
||||
GCC_MAJOR:=$(shell echo "$(GCC_VERSION)" | cut -d'.' -f1)
|
||||
GCC_MINOR:=$(shell echo "$(GCC_VERSION)" | cut -d'.' -f2)
|
||||
GCC_VER:=$(shell [ $(GCC_MAJOR) -gt 4 -o \( $(GCC_MAJOR) -eq 4 -a $(GCC_MINOR) -ge 7 \) ] && echo true)
|
||||
ifeq ($(GCC_VER), true)
|
||||
CFLAGS += -std=c++11 -DACL_USE_CPP11
|
||||
endif
|
||||
endif
|
||||
|
||||
# For FreeBSD
|
||||
ifeq ($(findstring FreeBSD, $(UNIXNAME)), FreeBSD)
|
||||
ifeq ($(findstring gcc, $(CC)), gcc)
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
endif
|
||||
CFLAGS += -DFREEBSD -D_REENTRANT
|
||||
SYSLIB = -lcrypt -lpthread -lz
|
||||
RPATH = freebsd
|
||||
endif
|
||||
|
||||
# For Darwin
|
||||
ifeq ($(findstring Darwin, $(UNIXNAME)), Darwin)
|
||||
# CC += -arch x86_64 -arch arm64
|
||||
CFLAGS += -DMACOSX -Wno-invalid-source-encoding \
|
||||
-Wno-invalid-offsetof
|
||||
UNIXTYPE = MACOSX
|
||||
SYSLIB += -liconv -rdynamic
|
||||
RPATH = macos
|
||||
endif
|
||||
|
||||
#Path for Linux
|
||||
ifeq ($(findstring Linux, $(UNIXNAME)), Linux)
|
||||
ifeq ($CC, "gcc")
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
endif
|
||||
ifeq ($(findstring i686, $(OSTYPE)), i686)
|
||||
RPATH = linux32
|
||||
endif
|
||||
ifeq ($(findstring x86_64, $(OSTYPE)), x86_64)
|
||||
RPATH = linux64
|
||||
endif
|
||||
ifeq ($(HAS_IO_URING), yes)
|
||||
SYSLIB += -luring
|
||||
endif
|
||||
ifeq ($(has_io_uring), yes)
|
||||
SYSLIB += -luring
|
||||
endif
|
||||
# CFLAGS += -DLINUX2 -D_REENTRANT
|
||||
CFLAGS += -D_REENTRANT
|
||||
SYSLIB += -lcrypt
|
||||
endif
|
||||
|
||||
#Path for SunOS
|
||||
ifeq ($(findstring SunOS, $(UNIXNAME)), SunOS)
|
||||
ifeq ($(findstring 86, $(UNIXNAME)), 86)
|
||||
SYSLIB += -lsocket -lnsl -lrt
|
||||
endif
|
||||
ifeq ($(findstring sun4u, $(UNIXNAME)), sun4u)
|
||||
SYSLIB += -lsocket -lnsl -lrt
|
||||
endif
|
||||
ifeq ($CC, "gcc")
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
endif
|
||||
CFLAGS += -DSUNOS5 -D_REENTRANT
|
||||
RPATH = sunos_x86
|
||||
endif
|
||||
|
||||
#Path for HP-UX
|
||||
ifeq ($(findstring HP-UX, $(UNIXNAME)), HP-UX)
|
||||
ifeq ($CC, "gcc")
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
endif
|
||||
CFLAGS += -DHP_UX -DHPUX11
|
||||
PLAT_NAME=hp-ux
|
||||
endif
|
||||
|
||||
# For CYGWIN
|
||||
ifeq ($(findstring CYGWIN, $(UNIXNAME)), CYGWIN)
|
||||
SYSLIB = -lpthread -rdynamic
|
||||
CFLAGS += -DLINUX2 -DMINGW
|
||||
UNIXTYPE = LINUX
|
||||
endif
|
||||
|
||||
# For MINGW
|
||||
ifeq ($(findstring MINGW, $(UNIXNAME)), MINGW)
|
||||
SYSLIB = -lpthread -rdynamic
|
||||
CFLAGS += -DLINUX2 -DMINGW
|
||||
UNIXTYPE = LINUX
|
||||
endif
|
||||
|
||||
# For MSYS
|
||||
ifeq ($(findstring MSYS, $(UNIXNAME)), MSYS)
|
||||
SYSLIB = -lpthread -rdynamic
|
||||
CFLAGS += -DLINUX2 -DMINGW
|
||||
UNIXTYPE = LINUX
|
||||
endif
|
||||
|
||||
#Find system type.
|
||||
ifneq ($(SYSPATH),)
|
||||
CHECKSYSRES = @echo "System is $(shell uname -sm)"
|
||||
endif
|
||||
###########################################################
|
||||
|
||||
CFLAGS += -I.. -I../../../lib_acl/include -I../../../lib_protocol/include -I../../../lib_acl_cpp/include \
|
||||
-I../../../lib_fiber/c/include -I../../../lib_fiber/cpp/include
|
||||
EXTLIBS =
|
||||
LDFLAGS = -L../../../lib_fiber/lib -lfiber_cpp \
|
||||
-L../../../lib_acl_cpp/lib -lacl_cpp \
|
||||
-L../../../lib_protocol/lib -lprotocol \
|
||||
-L../../../lib_acl/lib -lacl \
|
||||
-lfiber $(EXTLIBS) $(SYSLIB)
|
||||
|
||||
COMPILE = $(CC) $(CFLAGS)
|
||||
LINK = $(CC) $(OBJ) $(LDFLAGS)
|
||||
###########################################################
|
||||
OBJ_PATH = .
|
||||
|
||||
#Project's objs
|
||||
SRC = $(wildcard *.cpp)
|
||||
OBJ = $(patsubst %.cpp, $(OBJ_PATH)/%.o, $(notdir $(SRC)))
|
||||
|
||||
$(OBJ_PATH)/%.o: %.cpp
|
||||
$(COMPILE) $< -o $@
|
||||
|
||||
.PHONY = all clean
|
||||
all: RM $(OBJ)
|
||||
$(LINK) -o $(PROG)
|
||||
@echo ""
|
||||
@echo "All ok! Output:$(PROG)"
|
||||
@echo ""
|
||||
RM:
|
||||
rm -f $(PROG)
|
||||
clean cl:
|
||||
rm -f $(PROG)
|
||||
rm -f $(OBJ)
|
||||
|
||||
rebuild rb: clean all
|
||||
|
||||
install:
|
||||
cp $(PROG) ../../../dist/master/libexec/$(RPATH)/
|
||||
cp $(PROG).cf ../../../dist/master/conf/service/
|
||||
###########################################################
|
92
lib_fiber/samples/fiber_stack2/main.cpp
Normal file
92
lib_fiber/samples/fiber_stack2/main.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include "stdafx.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
class myfiber : public acl::fiber
|
||||
{
|
||||
public:
|
||||
myfiber(acl::fiber_tbox<bool>& box) : box_(box) {}
|
||||
~myfiber(void) {}
|
||||
|
||||
private:
|
||||
acl::fiber_tbox<bool>& box_;
|
||||
|
||||
// @override
|
||||
void run(void)
|
||||
{
|
||||
printf("fiber-%d-%d running\r\n", get_id(), acl::fiber::self());
|
||||
func1();
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
void func1(void)
|
||||
{
|
||||
func2();
|
||||
}
|
||||
|
||||
void func2(void)
|
||||
{
|
||||
func3();
|
||||
}
|
||||
|
||||
void func3(void)
|
||||
{
|
||||
box_.pop();
|
||||
}
|
||||
};
|
||||
|
||||
class checker : public acl::fiber
|
||||
{
|
||||
public:
|
||||
checker(acl::fiber_tbox<bool>& box, acl::fiber* fb, int n)
|
||||
: box_(box), fb_(fb), count_(n) {}
|
||||
~checker(void) {}
|
||||
|
||||
private:
|
||||
acl::fiber_tbox<bool>& box_;
|
||||
acl::fiber* fb_;
|
||||
int count_;
|
||||
|
||||
void run(void)
|
||||
{
|
||||
std::vector<acl::fiber_frame> stack;
|
||||
|
||||
for (int i = 0; i < count_; i++) {
|
||||
acl::fiber::stacktrace(*fb_, stack, 50);
|
||||
show_stack(stack);
|
||||
printf("\r\n");
|
||||
|
||||
stack.clear();
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
box_.push(NULL);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void show_stack(const std::vector<acl::fiber_frame>& stack)
|
||||
{
|
||||
for (std::vector<acl::fiber_frame>::const_iterator
|
||||
cit = stack.begin(); cit != stack.end(); ++cit) {
|
||||
printf("0x%lx(%s)+0x%lx\r\n",
|
||||
(*cit).pc, (*cit).func.c_str(), (*cit).off);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
acl::acl_cpp_init();
|
||||
acl::log::stdout_open(true);
|
||||
|
||||
acl::fiber_tbox<bool> box;
|
||||
acl::fiber* f = new myfiber(box);
|
||||
f->start();
|
||||
|
||||
acl::fiber* f2 = new checker(box, f, 10);
|
||||
f2->start();
|
||||
|
||||
acl::fiber::schedule();
|
||||
return 0;
|
||||
}
|
1
lib_fiber/samples/fiber_stack2/stdafx.cpp
Normal file
1
lib_fiber/samples/fiber_stack2/stdafx.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "stdafx.h"
|
24
lib_fiber/samples/fiber_stack2/stdafx.h
Normal file
24
lib_fiber/samples/fiber_stack2/stdafx.h
Normal file
@ -0,0 +1,24 @@
|
||||
// stdafx.h : 标准系统包含文件的包含文件,
|
||||
// 或是常用但不常更改的项目特定的包含文件
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//#include <iostream>
|
||||
//#include <tchar.h>
|
||||
|
||||
// TODO: 在此处引用程序要求的附加头文件
|
||||
|
||||
#include "lib_acl.h"
|
||||
#include "acl_cpp/lib_acl.hpp"
|
||||
#include "fiber/fiber.hpp"
|
||||
|
||||
#ifdef ACL_USE_CPP11
|
||||
#include "fiber/go_fiber.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user