编写代码只是程序员的工作之一,调试代码的时间甚至会超过编写代码,之前为大家讲解了很多关于系统、架构、编程等方面的内容,这篇文章就为大家全方位展示一次涉及到内核的 bug 排查过程。
继上周介绍了稳定性三大故障之一的ANR类故障后,本章继续介绍第二大类故障Crash/Tombstone及其分析定位方法。
Native Crash常常发生在带有Jni代码的APP中,或者系统的Native服务中。作为比较难分析的一类问题,Native Crash其实还是有较多的方法去定位。
前几天帮同事跟踪的一个程序莫名退出,没有core dump(当然ulimit是打开的)的问题。我们知道,正常情况下,如果程序因为某种异常条件退出的话,应该会产生core dump,而如果程序正常退出的话,应该是直接或者间接的调用了exit()相关的函数。 基于这个事实,我想到了这样一个办法,在程序开始时,通过系统提供的atexit(),向系统注册一个回调函数,在程序调用exit()退出的时候,这个回调函数就会被调用,然后我们在回调函数中打印出当前的函数调用栈,由此便可以知道exit()是在哪里调用,从而上述
调用栈描述的是函数之间的调用关系。调用栈由栈帧(Stack Frame)组成,每个栈帧对应着一个未运行完的函数。在GDB中可以用backtrace(简称bt)命令打印所有栈帧信息。若要用p命令打印一个非当前栈帧的局部变量,可以用frame命令选择另一个栈帧
函数在调用的时候会在调用栈中 push 一个调用帧,每次执行完函数都会逐一弹出调用帧知道所有函数执行完毕,调用栈被清空:
https://jackwish.net/2015/introduction-of-google-breakpad.html
不必太纠结于当下,也不必太忧虑未来,当你经历过一些事情的时候,眼前的风景已经和从前不一样了。——村上春树
在 Java 开发中,我们经常会遇到各种异常情况。当我们在线上环境发现 Java 报错提示异常信息,但是找不到问题时,打印异常的调用栈信息可以帮助我们迅速定位错误。本文将详细介绍如何使用 e.printStackTrace() 方法来打印 Java 异常的调用栈,并通过一个实例代码来加深理解。
程序在执行过程中 crash 是非常严重的问题,一般都应该在测试阶段排除掉这些问题,但是总会有漏网之鱼被带到 release 阶段。
原文链接:https://note.noxussj.top/?source=cloudtencent 什么是调用栈? 我们写的 JS 代码大多数都是同步模式,也就是从上往下依次执行。后一个任务必须要等
原文地址:https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif
今天该学习 Event Loop 啦,其实之前我写过一篇 Event Loop 的文章:
本文的目标是帮助大家深入理解Android系统资源异常之文件描述符异常,对于文件描述符异常的通用检测机制,当前包括fdtrack和fdsan两种机制展开剖析。
为了去野外烧烤,你创建了一堆的任务清单 - 一叠便条。对一叠便条会有如下操作:插入的待办事项放在清单的最前面;读取待办事项时,只读取最上面的,并将其删除。一叠便条就是栈,插入对应着栈的压入操作,读取并删除对应着栈的弹出操作。
软件环境:Python 3.7.0b4 一、基线条件和递归条件 由于递归函数调用自己,因此编写这样的函数时很容易出错,进而导致无限循环。例如: def countdown(i): print(i)
今天我们将学习一种优雅的问题解决方式--递归。 对于它,通常有3个阵营:恨它的、爱它的以及恨了几年后又爱上它。你属于哪一个? 1、递归 递归就是函数自己调用自己,但写递归很容易出错而导致死循环。 循环
ply 是 eBPF 的 front-end 前端工具之一,专为 embedded Linux systems 开发,采用 C 语言编写,只需 libc 和内核支持 BPF 就可以运行,不需要外部 kernel 模块,不需要 LLVM,不需要 python。
我们在应用程序的代码中添加业务日志的时候,不论是什么级别的日志,除了我们主动传给 Logger 让它记录的信息外,这行日志是由哪个函数打印的、所在的位置也是非常重要的信息,不然排查问题的时候很有可能就犹如大海捞针。
第3章 递归 递归 如果使用循环,程序的性能可能更高;如果使用递归,程序可能更容易理解。如何选择要看什么对你来说重要 很多算法都使用了递归,因此理解这种概念很重要 基线条件和递归条件 每个递归函数都有
递归是很多算法都使用的一种编程方法。听说递归是一种十分优雅的问题解决办法,可是对于初涉递归的我,还没有形成这种独特的体会。 学习使用递归的关键在于:如何将问题分为基线条件和递归条件。 基线条件和递归条件 由于递归函数调用自己,因此编写这样的函数时很容易出错,进而导致无限循环。 例如下面这个函数: def countdown(i): """倒计时""" print (i) countdown(i-1) 假设i的初始值为3,运行上述代码后: 3, 2, 1, 0, -1, -2,
Android OS由3层组成,最底层是Kernel,上面是Native bin/lib,最上层是Java层:
JavaScript 引擎是一个单线程解析器,而单线程解析器由堆和单一调用栈组成。浏览器提供 Web APIs,比如:DOM,AJAX 和 定时器。
该选项让链接器将所有符号添加到动态符号表中,这样才能将函数地址翻译成函数名,否则打印的结果是不会打印函数名的。
当时的我是一脸懵逼的,因为从来都没有听过这个专业名词。不过面试官还是很友好的,他说没关系,那你来做一道题,看看下面这段代码的执行结果是什么?
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
王竞原,负责网游刀锋铁骑项目,高级开发工程师,使用C++已有10年,非常喜欢C++,特别是C++11。希望能与广大的C++爱好者多交流。 一、什么是Android的C/C++ NativeCrash Android上的Crash可以分两种: 1、Java Crash java代码导致jvm退出,弹出“程序已经崩溃”的对话框,最终用户点击关闭后进程退出。 Logcat 会在“AndroidRuntime”tag下输出Java的调用栈。 2、Native Crash 通过NDK,使用C/C++开发,导致
不会等待这个任务结束才开始执行下一个任务,开启之后立即执行下一个任务,后续逻辑一般会通过回调函数的方式定义,异步模式对js 非常重要,没有异步任务单线程的 js 语言就无法同时处理大量耗时任务,单线程下面的异步最大的难点就是 代码的执行顺序混乱,Queue是消息队列队列也叫回调队列
主流的js 环境都是单线程吗模式执行js 代码, js采用为单线程的原因与最开始设计初衷有关,最早是运行在浏览器端的脚本语言,目的是为了实现页面上的动态交互,实现页面交互的核心就是dom操作,这也就决定了js必须使用单线程的模式来处理,不然就会造成严重的线程同步问题。如果js多个线程同时修改dom元素,此时浏览器就无法明确以那个线程的结果为准,为了避免这种线程同步问题,所以从一开始js就被设置成了单线程模式工作。这里所说的单线程指的是javascript执行环境中负责执行代码的线程只有一个。
我们往往在进行嵌入式开发的过程中,需要借助一些调试手段进行相关调试,比如在调试stm32的时候,可以在keil中利用jtag或者stlink进行硬件上的仿真与调试,一些高频的arm芯片也会使用jtag之类的硬件调试工具,还有trace32等等,但是这些往往需要借助一些硬件工具进行分析。当然,我们可以进行软件层面的分析。定位问题的方式通常有以下三点:
这时,你需要从 ES6 中引入的一个非常酷的新特性: Promise 来处理你的问题。
先做一个实验:来看看立即解决的 Promis 和立即超时( 0 毫秒的超时)哪个执行的更快?
在写这篇文章之前,我看了很多写的不错的文章,但是每篇文章都有那么几个关键的点,很多篇文章凑在一起综合来看,才可以对这些概念有较为深入的理解。所以,我就想要写这么一篇文章,结合自己的理解以及示例代码,用最通俗的文字表达出来。
一般来说,项目开发过程中,代码编写占开发总时间的40%,剩下的时间基本就是自测和联调的过程。程序出错很正常,关键是如何迅速的去定位它,修掉它。本文将介绍自己程序调试的一些常用方法,这边我以golang为例,总结为望问切闻---debug四部曲。
runtime包提供和go运行时环境的互操作,如控制go程的函数。它也包括用于reflect包的低层次类型信息;参见reflect报的文档获取运行时类型系统的可编程接口。
很多同学不知道为什么要用 debugger 来调试,console.log 不行么?
服务器部署会经常用到linux,很多时候都是用的时候上网查一下指令,然后用完过不了多久就忘记了,因此本文记录一些自己常用的linux指令,以作备忘。并不断添加。
简单说,就是打印一个文件夹下,所有文件名字,包括所有子文件夹中的文件。如果只是用 python 提供的内置模块,是非常容易。但是这题却限制了,不允许使用内置模块。
一、前言 xposed是一款安卓平台下强大的hook框架,我们可以用他来开发很多强大的插件,以此来帮助我们更方便地解决某些实际的问题。本文将尝试利用xposed来解决一个实际问题:如何批量地验证微信号
实现方式,通过拿到当前线程的所有调用栈信息,再遍历输出即可,虽然简单吧,但是实用呀,有时候一个方法报错了,没有异常调用栈,就比较难受了,加上这个方法,自己打调用栈。
本周跟着 Tasks, microtasks, queues and schedules 这篇文章一起深入理解这些概念间的区别。
在上面的设计中,结构是统一的,对外展现的是Parent,但是行为并非统一,当使用gdb打印调用栈时,是看不到Parent的影子的,当系统庞大后,对新人来理解系统会增加一些阻力。如何解决这个问题了?通过统一行为,就可以将这个清晰化。方法是:在Parent中增加一个非抽象方法,由这个新增加的非抽象方法来调用hello,这样在调用栈中就可以见到Parent的身影了,调用栈显示有层次感,有助于理解系统。
编译构建go程序 禁止优化 go build -gcflags "-N -l" ... 查看详细的编译过程命令 go build -x ... 补充:go build 编译选项:
valgrind安装:参考:https://blog.csdn.net/justheretobe/article/details/52986461
异常接管是操作系统对在运行期间发生异常的情况进行处理的一系列动作,譬如打印异常发生时当前函数调用栈信息、 cpu现场信息、任务的堆栈情况等。
日常的工作中,会收到一堆CPU使用率过高的告警邮件,遇到某台服务的CPU被占满了,这时候我们就要去查看是什么进程将服务器的CPU资源占用满了。通常我们会通过top或者htop来快速的查看占据CPU最高的那个进程,如下图:
开始之前先下载性能文件分析工具,下载地址: http://www.graphviz.org/download/
领取专属 10元无门槛券
手把手带您无忧上云