堆栈

【BPF】学习笔记 - BCC工具[6]

时光总嘲笑我的痴心妄想 提交于 2020-03-02 11:08:40
【BPF】学习笔记 - BCC工具[6] 本学习笔记来自于阅读 Brendan Gregg 的《BPF Performance Tools》 BPF编译器集合(BCC)是一个开放源代码项目,其中包含用于构建BPF软件的编译器框架和库。 它是BPF的主要前端项目,受到BPF开发人员的支持. BCC还包含70多个现成的BPF性能分析和故障排除工具 BCC 组件 : BCC包含有关工具,手册页和示例文件的文档,以及有关使用BCC工具的指南,以及有关BCC工具开发的指南和参考指南。 它提供了用于在Python,C ++中开发BCC工具的接口; 将来可能会添加更多接口 BCC工具使用的主要语言是Python(用于用户级组件)和C(用于内核级BPF)。指南中的建议之一是 “编写工具即可解决问题,而无需更多”. 这鼓励在可能的情况下开发 单一用途 的工具,而不是多功能的工具 一、 单一目的工具 Unix的哲学是做一件事并做好, 其中一种方式是创建较小的高质量工具,可以使用管道将它们连接在一起以完成更复杂的任务,例如 grep , cut 等 考虑一下如何为跟踪open系列syscall的一项任务自定义选项和输出: $ opensnoop -h usage: opensnoop [ -h ] [ -T ] [ -U ] [ -x ] [ -p PID ] [ -t TID ] [ -u UID ]

堆栈--后进先出

北慕城南 提交于 2020-03-02 10:31:17
//堆栈–>后进先出,先进后出 #include<stdio.h> #include<stdlib.h> struct stackNode{ int data; struct stackNode *nextPtr; }; typedef struct stackNode Stacknode; typedef Stacknode* StacknodePtr; void push(StacknodePtr *topPtr, int number); int pop(StacknodePtr *topPtr); void printList(StacknodePtr topPtr); int isEmpty(StacknodePtr topPtr); int main() { StacknodePtr startPtr = NULL; int choice; int value; printf("Enter your choice from the following.\n" " 1 to fill the number at the list top.\n" " 2 to remove the number from the list top.\n" " 3 to end.\n? "); scanf("%d", &choice); while(choice != 3){ switch

函数调用时参数传递规则

耗尽温柔 提交于 2020-03-02 05:32:06
ARM函数调用时参数传递规则 之前在学习如何在C语言中嵌入汇编时有了解到C语言之前的参数调用是使用寄存器 R0传递第一个参数, R1传递到第二个.. 一直到R3传递第四个参数. 但是 实际上有时可能传递的参数非常多,超过8个,或是参数中有浮点数之类,参数也会超过4个寄存器,对于超出的部份并不使用R4,而是使用堆栈的方式. 对于ARM体系来说,不同语言撰写的函数之间相互调用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedure Call Standard),ATPCS主要是定义了函数呼叫时参数的传递规则以及如何从函数返回,关于ATPCS的详细内容可以查看ADS1.2 Online Books ——Developer Guide的2.1节。这篇文档要讲的是 汇编代码中对C函数调用时如何进行参数的传递以及如何从C函数正确返回 不同于x86的参数传递规则,ATPCS建议函数的形参不超过4个,如果形参个数少于或等于4,则形参由R0,R1,R2,R3四个寄存器进行传递;若形参个数大于4,大于4的部分必须通过堆栈进行传递。 x86_64函数调用时参数传递规则 x86_64体系架构中函数调用时整数和指针参数按照从左到右的顺序依次保存在寄存器rdi,rsi,rdx,rcx,r8和r9中,浮点型参数保存在寄存器xmm0,xmm1......中

轻量级协程库-C语言实现

混江龙づ霸主 提交于 2020-03-02 03:23:41
协程(coroutine)顾名思义就是“协作的例程”(co-operative routines)。跟具有操作系统概念的线程不一样,协程是在用户空间利用程序语言的语法语义就能实现逻辑上类似多任务的编程技巧。实际上协程的概念比线程还要早,按照 Knuth 的说法 “子例程是协程的特例” ,一个子例程就是一次子函数调用,那么实际上协程就是类函数一样的程序组件,你可以在一个线程里面轻松创建数十万个协程,就像数十万次函数调用一样。只不过子例程只有一个调用入口起始点,返回之后就结束了,而协程入口既可以是起始点,又可以从上一个返回点继续执行,也就是说协程之间可以通过 yield 方式转移执行权, 对称(symmetric)、平级 地调用对方,而不是像例程那样上下级调用关系。当然 Knuth 的“特例”指的是协程也可以模拟例程那样实现上下级调用关系,这就叫 非对称协程 (asymmetric coroutines)。 基于事件驱动模型 我们举一个例子来看看一种 对称协程 调用场景,大家最熟悉的“生产者-消费者”事件驱动模型,一个协程负责生产产品并将它们加入队列,另一个负责从队列中取出产品并使用它。为了提高效率,你想一次增加或删除多个产品。伪代码可以是这样的: 1 2 3 4 5 6 7 8 9 10 11 12 13 # producer coroutine loop while queue

06.进程的虚拟内存管理.md

牧云@^-^@ 提交于 2020-03-01 22:15:45
正好遇到 华庭(庄命强)的glibc内存管理Ptmalloc2 源代码分析 一文,非常开心。真是大佬。我只是借着这篇文章稍微整理一下,为了以后自己回顾的时候能够更好的排查问题。 6.1 linux进程内存布局 x86 平台 Linux 进程内存布局   Linux 系统在装载 elf 格式的程序文件时,会调用 loader 把可执行文件中的各个段依次 载入到从某一地址开始的空间中(载入地址取决 link editor(ld)和机器地址位数,在 32 位机 器上是 0x8048000,即 128M 处)。如下图所示,以 32 位机器为例,首先被载入的是.text 段, 然后是.data 段,最后是.bss 段。这可以看作是程序的开始空间。程序所能访问的最后的地 址是 0xbfffffff,也就是到 3G 地址处,3G 以上的 1G 空间是内核使用的,应用程序不可以直 接访问。  &emsp应用程序的堆栈从最高地址处开始向下生长,.bss 段与堆栈之间的空间是空闲的, 空闲空间被分成两部分,一部分为 heap,一部分为 mmap 映射区域,mmap 映射区域一般 从 TASK_SIZE/3 的地方开始,但在不同的 Linux 内核和机器上,mmap 区域的开始位置一般是 不同的。Heap 和 mmap 区域都可以供用户自由使用,但是它在刚开始的时候并没有映射到 内存空间内,是不可访问的

C处理不定参数(va_start)

隐身守侯 提交于 2020-03-01 15:55:47
在#include<stdarg.h>头里包含了四个宏 #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //第一个可选参数地址 #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址 #define va_end(ap) ( ap = (va_list)0 ) 函数实现的原理: 首先:进程中的堆栈地址是从高到底分配的,那么执行一个函数的过程: 先把参数地址入栈,接着是函数返回值地址入栈,接着入栈函数的执行代码。这个过程中地址不断递减(一些黑客就在这个过程中加入自己的代码执行) 最后一个参数地址 (最高地址) 倒数第二个参数地址 (次之) 。。 第一个参数 (参数列表最低地址) 函数返回值 函数执行代码 例子: void arg_test(int i, ...) { int j=0; va_list arg_ptr; va_start(arg_ptr, i); printf("&i = %p\n", &i);//打印参数i在 堆栈 中的地址 printf("arg_ptr

java异常堆栈信息丢失

假如想象 提交于 2020-03-01 15:11:57
在生产环境上看到tomcat/log/gate.log一直输出异常信息,但是不见异常堆栈信息。 Java .lang.NullPointerException java.lang.NullPointerException java.lang.NullPointerException java.lang.NullPointerException 最开始怀疑是log4j的使用方式有问题,导致打印不出来,但是当前的使用方式只会丢失rootCause,不会丢弃所有的异常堆栈。 catalina.out中就以为是使用了标准输出打印异常类名...。事实当然不是这样,后来查看了异常处理点,基本上都会调用 printStackTrace(),然后调用log4j来输出异常到其他文件。说明异常的堆栈信息确实丢失了。 异常堆栈丢失了,然后google之, stackoverflow答案 。从别人的回答中,可以看到,这里可能是jvm优化时,产生的结果。 当增加虚拟机参数-XX:-OmitStackTraceInFastThrow后,不见异常堆栈信息丢失。 来源: oschina 链接: https://my.oschina.net/u/123079/blog/755229

异常处理.深度跟踪

杀马特。学长 韩版系。学妹 提交于 2020-03-01 15:11:30
方式1:traceback捕捉堆栈详细异常 1.traceback模块儿可打印异常发生时与函数调用堆栈相关的信息,函数可能多层嵌套,从被调用的函数依次搜索调用者并匹配异常处理程序,这个过程被称为"辗转开解",解释器一方面维护放置堆栈中函数有关信息,另一方面也维护着与已从堆栈中"辗转开解"函数有关信息 2.traceback模块儿print_exc()方法直接打印堆栈异常无返回,format_exc()方法返回堆栈异常信息 import traceback try: rhandler = open('unused.txt', 'r+b') except IOError as io_err: rhandler = None traceback.print_exc() finally: if rhandler: rhandler.close() 方式2:sys回溯最后异常 1.sys.exc_info()返回值是一个tuple,(异常的类型, 异常的信息或参数, 调用堆栈的信息对象) import sys try: rhandler = open('unused.txt', 'r+b') except IOError as io_err: rhandler = None exc_type, exc_value, exc_trace = sys.exc_info() print '''\

内存越界的问题

≯℡__Kan透↙ 提交于 2020-03-01 08:02:03
在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。 来源: CSDN 作者: 蓝谷芮济 链接: https://blog.csdn.net/weixin_42577143/article/details/104572874

7-6 堆栈操作合法性(20 分)

≡放荡痞女 提交于 2020-02-29 15:31:06
7-6 堆栈操作合法性(20 分) 假设以 S 和 X 分别表示入栈和出栈操作。如果根据一个仅由 S 和 X 构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入 S 和 X 序列,判断该序列是否合法。 输入格式: 输入第一行给出两个正整数N和M,其中N是待测序列的个数,M( ≤ 5 0)是堆栈的最大容量。随后N行,每行中给出一个仅由 S 和 X 构成的序列。序列保证不为空,且长度不超过100。 输出格式: 对每个序列,在一行中输出 YES 如果该序列是合法的堆栈操作序列,或 NO 如果不是。 输入样例: 4 10 SSSXXSXXSX SSSXXSXXS SSSSSSSSSSXSSXXXXXXXXXXX SSSXXSXXX 输出样例: YES NO NO NO思路:不会有人去建堆栈吧吧吧叭叭叭 #include<string> #include<iostream> using namespace std; int main() { string str; int n, m; cin >> n >> m; getchar(); while (n--){ int cnt = 0; str.clear(); getline(cin, str); int flag = 0; for (int i =