flyer0402 / zz

zzzz
0 stars 0 forks source link

linux 分析以及调试 #4

Open flyer0402 opened 1 year ago

flyer0402 commented 1 year ago

udev基本用法及原理 新的方法是采用NETLINK实现的,这是一种特殊类型的socket,专门用于内核空间与用户空间的异步通信。下面的这个简单的例子,可以监听来自内核hotplug的事件。

include

include

include

include

include <sys/un.h>

include <sys/ioctl.h>

include <sys/socket.h>

include <linux/types.h>

include <linux/netlink.h>

include

include

include <arpa/inet.h>

include <netinet/in.h>

define UEVENT_BUFFER_SIZE 2048

static int init_hotplug_sock()
{
const int buffersize = 1024;
int ret;

struct sockaddr_nl snl;
bzero(&snl, sizeof(struct sockaddr_nl));
snl.nl_family = AF_NETLINK;
snl.nl_pid = getpid();
snl.nl_groups = 1;

int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
if (s == -1)
{
perror("socket");
return -1;
}
setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));

ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));
if (ret < 0)
{
perror("bind");
close(s);
return -1;
}

return s;
}

int main(int argc, char* argv[])
{
int hotplug_sock = init_hotplug_sock();

while(1)
{
/ Netlink message buffer /
char buf[UEVENT_BUFFER_SIZE * 2] = {0};
recv(hotplug_sock, &buf, sizeof(buf), 0);
printf("%s\n", buf);

/* USB 设备的插拔会出现字符信息,通过比较不同的信息确定特定设备的插拔,在这添加比较代码 */

} return 0;
}

https://blog.csdn.net/zhaominyong/article/details/127685490

flyer0402 commented 1 year ago

gdb调试

dump内存内容 对应有些内存泄漏问题,可能是一种debug方式 在gdb调试过程中(甚至是在调试coredump时),将程序内存中的内容dump到指定文件中 通过gdb dump出相关内存: dump binary memory memory.bin 0x7f0537f000 0x7f05413000

memory.bin 指定文件。相对路径 通过 hexdump -C memory.bin > 1.txt 命令 ,将内存转成字符串形式,打开文件查询内容

https://yuque.antfin.com/idmdo7/pvtm7i/aic18k?

https://yuque.antfin.com/xsg183219/ggq168/ahe2py

https://blog.csdn.net/diyudong4681/article/details/101201098

flyer0402 commented 1 year ago

linux 内存回收 https://zhuanlan.zhihu.com/p/72998605 https://zhuanlan.zhihu.com/p/70964195 https://zhuanlan.zhihu.com/p/93228929

flyer0402 commented 1 year ago

cmake 指定c++11 set (CMAKE_CXX_STANDARD 11)

flyer0402 commented 1 year ago

EBPF 比较详细的文档 https://coolshell.cn/articles/22320.html

flyer0402 commented 1 year ago

mlock实现原理 https://www.lmlphp.com/user/92895/article/item/1783132/

https://blog.csdn.net/feelabclihu/article/details/123288206

static void mlockExecutable() { char buf[4096]; char flags[8]; FILE *fp; unsigned long start, end;

fp = fopen("/proc/self/maps", "r");
if (fp) {
    while (fgets(buf, sizeof(buf), fp)) {
        start = 0;
        end = 0;
        flags[2] = '\0';
        flags[4] = '\0';
        sscanf(buf, "%lx-%lx %4c ", &start, &end, flags);
        if (start > 0 && end > start && flags[2] == 'x') {
            mlock2((void *)start, end - start, MLOCK_ONFAULT);
        }
    }
    fclose(fp);
}

} weston.service LimitMEMLOCK=infinity CapabilityBoundingSet=CAP_SYS_NICE CAP_SYS_RESOURCE CAP_SYS_ADMIN CAP_SYSLOG CAP_DAC_OVERRIDE CAP_NET_ADMIN CAP_NET_RAW CAP_IPC_LOCK

flyer0402 commented 1 year ago

读写锁内核实现 https://blog.csdn.net/feelabclihu/article/details/130896206?spm=1001.2014.3001.5502

flyer0402 commented 1 year ago

内核工匠博客 https://blog.csdn.net/feelabclihu?type=blog

flyer0402 commented 1 year ago

Android关于socket和binder使用场景的选择问题 https://blog.csdn.net/rzleilei/article/details/125770598

flyer0402 commented 1 year ago

内核锁、抢占、中断场景 https://blog.csdn.net/u012294613/article/details/123365262 https://blog.csdn.net/feelabclihu/article/details/129631033?spm=1001.2014.3001.5502 https://blog.csdn.net/chbgoon/article/details/123495480 https://blog.csdn.net/u012294613/article/details/123878531?ops_request_misc=&request_id=093ec2f0ec404ba883be6f38d94381b0&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~koosearch~default-5-123878531-null-null.268^v1^control&utm_term=%E8%87%AA%E6%97%8B%E9%94%81&spm=1018.2226.3001.4450

flyer0402 commented 1 year ago

Linux 环境变量之 LD_PRELOAD & LD_LIBRARY_PATH & LD_DEBUG https://blog.csdn.net/llm_hao/article/details/115493516

g++ attr_test.cpp attr_constructor_test.cpp -fPIC -shared -o libattrtest.so g++ debuggerd_test.cpp -fPIC -shared -o libdebuggerd.so

Add to /usr/lib/

cp libdebuggerd.so /usr/lib/ cp libdebuggerd.so /usr/lib/ g++ main.cpp -o main -lattrtest -ldl

or add path

export LD_LIBRARY_PATH=/workspace/my_debug/attr_constructor/ g++ main.cpp -o main -L. -lattrtest -ldl

// attr_test.cpp

include

include

include

include

void dosometest() { printf("xxxxxxxxxxxxxxxxxxxxxxx\n"); }

//attr_test.h

include

include

include

include

void dosometest();

attr_constructor_test.cpp

include

include

include

include

static void __init_debugger(void) attribute ((constructor));

static void __init_debugger(void) { printf("dhm __init_debugger \n"); void* handle = dlopen("libdebuggerd.so", RTLD_LAZY); if (handle == NULL) { //LOG_E("Fail to load debugger: %s", dlerror()); printf("dhm just test \n"); } }

debuggerd_test.cpp

include

include

include

include

include

include

//#include <sys/stat.h> //#include <sys/ptrace.h> //#include <sys/types.h> //#include <asm/unistd.h>

//#include <sys/syscall.h> //#include <sys/ptrace.h> //#include

static void init_debugger_sighandler(void) attribute__ ((constructor));

static void __init_debugger_sighandler(void) { // struct sigaction action; // memset(&action, 0, sizeof(action)); // sigemptyset(&action.sa_mask); // action.sa_sigaction = debuggerd_signal_handler; // action.sa_flags = SA_RESTART | SA_SIGINFO;

printf("dhm __init_debugger_sighandler begin\n");

// sigaction(SIGABRT, &action, NULL); // sigaction(SIGBUS, &action, NULL); // sigaction(SIGFPE, &action, NULL); // sigaction(SIGILL, &action, NULL); // sigaction(SIGSEGV, &action, NULL); // sigaction(SIGTRAP, &action, NULL); } main.cpp

include

include"attr_test.h"

int main() { printf("-----------test main -----------------\n"); dosometest(); return 0; }

dhm __init_debugger dhm __init_debugger_sighandler begin -----------test main ----------------- xxxxxxxxxxxxxxxxxxxxxxx

flyer0402 commented 1 year ago

非法指令(Illegal Instruction)问题定位,比较实用 https://www.cnblogs.com/arnoldlu/p/10815908.html

flyer0402 commented 1 year ago

mesa架构分析 https://blog.csdn.net/HaoBBNuanMM/article/details/109054106

flyer0402 commented 11 months ago

首先使用simg2img将其解压为raw image, 然后用mount 挂载。 如 out/host/linux-x86/bin/simg2img out/target/product//system.img raw_system.img sudo mount -t ext4 raw_system.img /mnt/android/system

原文链接:https://blog.csdn.net/doon/article/details/50460783

flyer0402 commented 11 months ago

内核kasan https://www.kernel.org/doc/html/latest/translations/zh_CN/dev-tools/kasan.html

flyer0402 commented 10 months ago

Linux RT 进程引发内核频繁卡死的优化方案,RT_RUNTIME_SHARE 解决长期占用问题 https://zhuanlan.zhihu.com/p/592166773 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-5.4.y&id=423f2695007ddb379b86fceb6c10a42e84794158

flyer0402 commented 10 months ago

PTHREAD_MUTEX_NORMAL

这种类型的互斥锁不会自动检测死锁。如果一个线程试图对一个互斥锁重复锁定,将会引起这个线程的死锁。如果试图解锁一个由别的线程锁定的互斥锁会引发不可预料的结果。如果一个线程试图解锁已经被解锁的互斥锁也会引发不可预料的结果。

PTHREAD_MUTEX_ERRORCHECK

这种类型的互斥锁会自动检测死锁。如果一个线程试图对一个互斥锁重复锁定,将会返回一个错误代码。如果试图解锁一个由别的线程锁定的互斥锁将会返回一个错误代码。如果一个线程试图解锁已经被解锁的互斥锁也将会返回一个错误代码。

PTHREAD_MUTEX_RECURSIVE

如 果一个线程对这种类型的互斥锁重复上锁,不会引起死锁,一个线程对这类互斥锁的多次重复上锁必须由这个线程来重复相同数量的解锁,这样才能解开这个互斥 锁,别的线程才能得到这个互斥锁。如果试图解锁一个由别的线程锁定的互斥锁将会返回一个错误代码。如果一个线程试图解锁已经被解锁的互斥锁也将会返回一个 错误代码。这种类型的互斥锁只能是进程私有的(作用域属性为PTHREAD_PROCESS_PRIVATE)。

PTHREAD_MUTEX_DEFAULT

这种类型的互斥锁不会自动检测死锁。如果一个线程试图对一个互斥锁重复锁定,将会引起不可预料的结果。如果试图解锁一个由别的线程锁定的互斥锁会引发不可预料的结果。如果一个线程试图解锁已经被解锁的互斥锁也会引发不可预料的结果。POSIX标准规定,对于某一具体的实现,可以把这种类型的互斥锁定义为其他类型的互斥锁。 https://www.cnblogs.com/jingzhishen/p/3461727.html

flyer0402 commented 10 months ago

内核工匠-Linux内核性能剖析的方法学和主要工具 https://blog.csdn.net/feelabclihu/article/details/125568230?spm=1001.2014.3001.5502

flyer0402 commented 9 months ago

audit2allow 权限查看工具 https://blog.csdn.net/jackone12347/article/details/123500552 https://blog.csdn.net/pan0755/article/details/115798825 https://blog.csdn.net/tung214/article/details/72734086

flyer0402 commented 9 months ago

init https://blog.csdn.net/weixin_45767368/article/details/130149845

flyer0402 commented 9 months ago

kernel 异常以及ram console https://www.cnblogs.com/wangjie1990/p/11327676.html https://www.cnblogs.com/bobfly1984/p/14142094.html https://zhuanlan.zhihu.com/p/545560128 https://blog.csdn.net/hanxuan12233/article/details/122964986 https://blog.csdn.net/zydlyq/article/details/50997582

flyer0402 commented 9 months ago

QNX startup程序分析 https://www.jianshu.com/p/7f4e5bc420fa

flyer0402 commented 9 months ago

linux 浅析安全启动(Secure Boot) https://zhuanlan.zhihu.com/p/540171344

flyer0402 commented 6 months ago

https://www.cnblogs.com/wangbin/p/8862698.html [epoll_wait 时 POLLERR 与 POLLIN 同时返回的现象解析]

flyer0402 commented 5 months ago

虚表指针 https://blog.csdn.net/fcsfcsfcs/article/details/116406860

flyer0402 commented 4 months ago

信号内核处理/ https://blog.csdn.net/LHRan_ran_/article/details/136791041 https://www.cnblogs.com/gnuemacs/p/14311120.html

flyer0402 commented 3 months ago

内核调试 https://blog.csdn.net/yunlianglinfeng/article/details/71330696

flyer0402 commented 2 months ago

bootchart https://blog.csdn.net/nei504293736/article/details/109246910

flyer0402 commented 2 months ago

egl gbm https://blog.csdn.net/weixin_45730790/article/details/130830789

flyer0402 commented 2 months ago
  1. static修饰全局变量和函数时,会改变全局变量和函数的链接属性-------变为只能在内部链接,从而使得全局变量的作用域变小 https://blog.csdn.net/weixin_45031801/article/details/134215425
flyer0402 commented 2 months ago

sigbus分析 https://www.hikunpeng.com/developer/techArticles/20230828-5

flyer0402 commented 2 months ago

bpf https://blog.csdn.net/feelabclihu/article/details/130652632?spm=1001.2014.3001.5502

flyer0402 commented 2 months ago

codelinaro https://www.codelinaro.org/

flyer0402 commented 2 months ago

codesourcery 和Linaro简介,ARM Toolchain

https://blog.csdn.net/timeless_2014/article/details/82346433

flyer0402 commented 2 months ago

asan和hwasan https://blog.csdn.net/21cnbao/article/details/107096665

flyer0402 commented 1 month ago

https://blog.csdn.net/PlutoZuo/article/details/134824248 https://www.kernel.org/

flyer0402 commented 1 month ago

android镜像文件dump出来 cd /dev/block/by-name/ ls -la | grep ivi_app_a lrwxrwxrwx 1 root root 10 Sep 20 15:17 ivi_app_a -> /dev/vda16 dd if=/dev/vda16 of=/sdcard/boot_b.img hexdump /sdcard/boot_b.img https://blog.csdn.net/weixin_43890033/article/details/114966941

flyer0402 commented 2 days ago

include "stdlib.h"

include <sys/mman.h>

namespace { struct Frame { Frame(intptrt **fp) : fp(fp) { callerfp = fp[0]; callerpc = fp[1];

caller_caller_fp_ = reinterpret_cast<intptr_t**>(caller_fp_)[0];
caller_caller_pc_ = reinterpret_cast<intptr_t**>(caller_fp_)[1];

}

~Frame() { intptr_t maybe_callerfp = fp[0]; intptr_t maybe_callerpc = fp[1];

intptr_t *maybe_caller_caller_fp = reinterpret_cast<intptr_t**>(maybe_caller_fp)[0];
intptr_t *maybe_caller_caller_pc = reinterpret_cast<intptr_t**>(maybe_caller_fp)[1];

if ((maybe_caller_fp != caller_fp_) ||
    (maybe_caller_pc != caller_pc_) ||
    (maybe_caller_caller_fp != caller_caller_fp_) ||
    (maybe_caller_caller_pc != caller_caller_pc_)) {
  LOG_E("getActiveNetworkStatus stack frame corrupted, abort");
  abort();
} else {
  LOG_I("caller's frame info, fp: 0x%lx pc: 0x%lx", caller_fp_, caller_pc_);
  LOG_I("caller's caller's frame info, fp: 0x%lx pc: 0x%lx", caller_caller_fp_, caller_caller_pc_);
}

}

intptrt **fp;

// v8::internal::FunctionCallbackArguments::Call intptr_t callerfp; intptr_t callerpc;

// v8::internal::HandleApiCallHelper intptr_t caller_callerfp; intptr_t caller_callerpc; }; }

// 函数内使用 void getActiveNetworkStatus(const FunctionCallbackInfo &args) { intptr_t **fp; asm ("mov %0, x29" : "=r" (fp)); Frame frame(fp);

frame info:

entering getActiveNetworkStatus exiting getActiveNetworkStatus caller's fp 0x7fe5facff0 (x21) 0x7fe5facff0 (x29[0]) caller's pc 0x7fb433ca58 (x25) 0x7fb433ca58 (x29[1]) caller's caler's fp 0x7fe5fad0f0 (x23) 0x7fe5fad0f0 caller's caller's pc 0x7fb433d890 (x24) 0x7f3d5159e8

// 使用mprotect跟踪栈地址,有修改则coredump void getActiveNetworkStatus(const FunctionCallbackInfo &args) { intptr_t *fp; char p[1024]; asm ("mov %0, x29" : "=r" (fp)); Frame frame(fp); p[1023] = '\0'; void data=&p[1023]; long page_size = 4096; char aligned_start = (char )((uintptr_t)data & ~(page_size - 1)); char aligned_end = (char )((uintptr_t)(data + 4096 + page_size - 1) & ~(page_size - 1));

if (mprotect(aligned_start, aligned_end - aligned_start, PROT_READ) != 0) {
    LOG_D("%s error", __func__);
}
   LOG_D("%s", __func__);
if (!linkclientReady) {
    LOG_E("%s: linkClient is destroyed %p", __func__,&p);
    return;
}

auto netStatus = linkClient->getActiveNetworkStatus();
Isolate *isolate = Isolate::GetCurrent();
if (netStatus == NULL) {
    LOG_I("getActiveNetworkStatus Null %p %p  %p %p %p",fp,&p,&p[1023],aligned_start,aligned_end);
    if (mprotect(aligned_start, aligned_end - aligned_start, PROT_READ|PROT_WRITE) != 0) {
        LOG_D("%s error", __func__);
    }
    returnValue(args, Null(isolate));
    return;
}
Local<Object> result = Object::New(isolate);
fillNetworkStatus(isolate, *netStatus, result);
LOG_I("getActiveNetworkStatus: %s", netStatus->toString().c_str());
args.GetReturnValue().Set(result);
if (mprotect(aligned_start, aligned_end - aligned_start, PROT_READ|PROT_WRITE) != 0) {
    LOG_D("%s error", __func__);
}
flyer0402 commented 2 days ago

通过分析, 栈被踩坏, 踩坏的位置固定 ,尝试对栈添加保护 patch 如下, 栈扩容后,确保子函数栈内地址,在保护地址范围之外 http://gerrit3.alibaba-inc.com/c/git/yunos/tianmu/framework/npm/net_monitor/+/1214777

上述,在栈被踩坏时,触发sig11 ,si_code 2 ,保留了现场 通过coredump 分析, 火山的 _ZN15CompileListener17onCompileProgressEf 向x0写入了一个值,x0 地址是主线程中栈地址 +96 是 调用 onCompileProgress 函数, 通过汇编分析 与调用方代码分析 这个函数地址保存_InleApp中, x0与函数相同方式取出, x0 也是 _InleApp 变量 但没有_InleApp 的数据结构

猜测 compile 函数传的 progress被保存在 InleApp 中, 这个是栈上地址, 只能当前栈内使用 296   float progress = 0; 297   _InleApp->compile(outputFile, "", 1280, 720, 0, 0, -1, 30, 21, &progress/, 4096 2 1024/);