Linux基础调试方法总结

【基础技能】Linux PHY驱动调试方法 https://gitee.com/lee790608/linuxPhyDriver STEP1 准备硬件环境 1. 开发环境,可以修改内核代码,编译 2. 硬件开发板,可以进入系统调试,可以传送代码(常用的ADB打通即可) 3. PHY芯片,最好是贴在开发板上,如果飞线,对走线信号要求非常高(尤其是SGMII) 4. 示波器,方便抓取MDIO / SGMII总线信号 STEP2 获取VDD和V... 阅读详情

一、编译链指令的使用方法

1.1、驱动panic

88260.548903][T29361] phyparamdev-D:zzlstk6a7x_init:273
[88260.583798][T29361] Unable to handle kernel paging request at virtual address 006b6b6b6b6b6b7b
[88260.592541][T29361] Mem abort info:
[88260.596158][T29361]   ESR = 0x96000004
[88260.599973][T29361]   EC = 0x25: DABT (current EL), IL = 32 bits
[88260.606057][T29361]   SET = 0, FnV = 0
[88260.609914][T29361]   EA = 0, S1PTW = 0
[88260.613803][T29361]   FSC = 0x04: level 0 translation fault
[88260.619441][T29361] Data abort info:
[88260.623207][T29361]   ISV = 0, ISS = 0x00000004
[88260.627782][T29361]   CM = 0, WnR = 0
[88260.631489][T29361] [006b6b6b6b6b6b7b] address between user and kernel address ranges
[88260.639375][T29361] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
[88260.646406][T29361] Skip md ftrace buffer dump for: 0x1609e0
[88260.652080][T29361] Modules linked in: phyparam(OE+) swt6652_wifi(OE) skw_sdio_v20(OE) gadget(OE) fuelgauge(OE) charger(OE) keypad(OE) kcodec(OE) msgkit(OE) kbase(OE) m
88261.109559][T29361] Hardware name: Qualcomm Technologies, Inc. BENGAL IDP nopmi (DT)
[88261.117312][T29361] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[88261.124980][T29361] pc : stk6a7x_init+0x1d0/0x454 [phyparam]
[88261.130699][T29361] lr : stk6a7x_init+0x1b8/0x454 [phyparam]
[88261.136405][T29361] sp : ffffffc0212d39a0
[88261.140420][T29361] x29: ffffffc0212d3a00 x28: ffffffc026ffc778 x27: ffffffc026ff8898
[88261.148268][T29361] x26: 6b6b6b6b6b6b6b6b x25: ffffffdb2e32e780 x24: ffffffdb2e32df60
[88261.156115][T29361] x23: ffffffdb2e32e1b0 x22: ffffffdb2e32e000 x21: ffffffdb2e32e000
[88261.163960][T29361] x20: ffffff80270a3200 x19: ffffffdb2e32d438 x18: ffffffc00f62e068
[88261.171804][T29361] x17: 0000f4040044ffff x16: 0000000000098c3c x15: 0000000005f5e100
[88261.179650][T29361] x14: 0000000005f5e100 x13: 0000000000000000 x12: ff80005b2ad5b670
[88261.187495][T29361] x11: ffffffdb2ad5b670 x10: ffffffdb2ad5b670 x9 : 2c458a220a2c7e00
[88261.195341][T29
[88261.124980][T29361] pc : stk6a7x_init+0x1d0/0x454 [phyparam]
[88261.130699][T29361] lr : stk6a7x_init+0x1b8/0x454 [phyparam]
[88261.136405][T29361] sp : ffffffc0212d39a0
[88261.140420][T29361] x29: ffffffc0212d3a00 x28: ffffffc026ffc778 x27: ffffffc026ff8898
[88261.148268][T29361] x26: 6b6b6b6b6b6b6b6b x25: ffffffdb2e32e780 x24: ffffffdb2e32df60
[88261.156115][T29361] x23: ffffffdb2e32e1b0 x22: ffffffdb2e32e000 x21: ffffffdb2e32e000
[88261.163960][T29361] x20: ffffff80270a3200 x19: ffffffdb2e32d438 x18: ffffffc00f62e068
[88261.171804][T29361] x17: 0000f4040044ffff x16: 0000000000098c3c x15: 0000000005f5e100
[88261.179650][T29361] x14: 0000000005f5e100 x13: 0000000000000000 x12: ff80005b2ad5b670
[88261.187495][T29361] x11: ffffffdb2ad5b670 x10: ffffffdb2ad5b670 x9 : 2c458a220a2c7e00
[88261.195341][T29361] x8 : 2c458a220a2c7e00 x7 : 0000000000000001 x6 : fefefefefefeff32
[88261.203186][T29361] x5 : 8080808080808000 x4 : 0000000000000008 x3 : ffffff80341c8040
[88261.218870][T29361] Call trace:
[88261.222018][T29361]  stk6a7x_init+0x1d0/0x454 [phyparam]
[88261.227376][T29361]  phyparam_dev_create+0x144/0x710 [phyparam]
[88261.233341][T29361]  init_module+0x110/0xfc4 [phyparam]
[88261.238613][T29361]  do_one_initcall+0x7c/0x2d8
[88261.243164][T29361]  do_init_module+0x60/0x730
[88261.247614][T29361]  load_module+0xef0/0x11b4
[88261.251977][T29361]  __do_sys_init_module+0x334/0x3bc
[88261.257038][T29361]  __arm64_sys_init_module+0x20/0x30
[88261.262184][T29361]  invoke_syscall+0x60/0x150
[88261.266644][T29361]  el0_svc_common+0xc8/0x114
[88261.271102][T29361]  do_el0_svc+0x28/0x98
[88261.275118][T29361]  el0_svc+0x28/0x90
[88261.278882][T29361]  el0t_64_sync_handler+0x88/0xec
[88261.283773][T29361]  el0t_64_sync+0x1b8/0x1bc
[88261.288137][T29361] Code: f2b26c00 f0000082 f2dc51c0 91204042 (f9400b56) 
[88261.294935][T29361] ---[ end trace 721f7b1dea727321 ]---
[88261.300256][T29361] Kernel panic - not syncing: Oops: Fatal except

从上述panic日志发现驱动加载挂在stk6a7x_init函数内部,但是不知道具体函数内部在哪里空指针
可以通过pc指针追溯

pc : stk6a7x_init+0x1d0/0x454 [phyparam]

从这句可以分析出
0x1d0 ✅ 是 pc(程序计数器)在函数内的偏移,也就是 crash 发生在 stk6a7x_init 函数开始后的第 0x1d0 字节。
0x454 ✅ 是 函数总大小(字节数),也就是 stk6a7x_init 从开始到结束占据的总机器码长度。
这里的偏移都是从函数起始地址(函数本身的第一个指令)算起的,也就是从0开始计数的

函数 stk6a7x_init 的机器码布局(简化):
地址: 0x6c0   0x6c4   0x6c8   … … 0xA14 (长度 0x454)
偏移:   0       4       8        … … 0x454

0x0 → 函数起始指令
0x1d0 → 函数内部某条指令(crash 位置)
0x454 → 函数总长度

1.2、如何依据pc指针使用addr2line解析源码行号

aarch64-linux-android24-addr2line -e phyparam.ko 0x1d0
??:0

解析不出信息,因为用的偏移地址不对,0x1d0是函数内偏移,而addr2line需要的模块的虚拟地址或符号偏移,正确步骤如下所示:

aarch64-linux-android24-nm -n phyparam.ko | grep stk6a7x_init
00000000000006c0 t stk6a7x_init
000000000000aa78 t stk6a7x_init.cfi_jt

解析出stk6a7x_init函数首地址为0x6c0,偏移为0x1d0,实际为0x980

aarch64-linux-android24-addr2line -e phyparam.ko 0x890 -f -C
stk6a7x_xxx_pid
xxxx/stk6a7x.c:208

1.3、内核panic

[20250312-15:04:10] [15.828142]
[20250312-15:04:10][ Internal error: Oops: 805 [#1] PREEMPT SMP ARM.
[20250312-15:04:10][15.848559j cPU: 0 PID: 1648 Comm: ipc_server Tainted: G15.834276] Modules linked in: 1500_i2s(0) it662x(0) videoip(0) ssp(0) it6805(0) ast_vc(0) msgkit(0) kmedia(0) hwswitch(0) kbase(0) keypad(o)
o4.9.0 #1
[20250312-15:04:10][15.862181]15.856824] Hardware name: Generic Dr based system
[20250312-15:04:10][task: b4fa1e00 task.stack: b106a000
[20250312-15:04:10][15.867242] PC is at_unix_insert_socket+0x4c/0x70
[20250312-15:04:10] [15.872684]LR is at unix create1+0x150/0x1c4
[20250312-15:04:10][15.8775451]pc:[<804375ac>]lr:[<80438fb4>]psr: a0010013
[20250312-15:04:10][15.8775451sp:b106bef0ip:b106bf088fp:b106bf04
[20250312-15:04:10][15.890369]]r10:00000000r9 :00000000r8 :00000000
[20250312-15:04:10][15.896204]1 r7 : b1a9a9a9r6 :80605254r5:806050f8r4 :b1180000
[20250312-15:04:10] [15.903485]r3 : f8fcf7a99r2 :b1180034 r1 : 00000000 r0 : 806050f8
[20250312-15:04:10] [15.918729]Control: 10c5387dTable: b113006a1DAC: 00000055
[20250312-15:04:10] [15.925143]Process ipc_server (pid: 1648, stack limit = 0xb106a210)
[20250312-15:04:10] [15.932232] Stack:(0xb106bef0 to 0xb106c000)
[20250312-15:04:10] [15.937092]1 bee0:80604a54 b1180000 b106bf34 b106bf08
[20250312-15:04:10][15.946219] 1bf00: 80438fb4 8043756c 00000000 b106bf18 804a6ae4 80439028 b491d800 805a8ecc
[20250312-15:04:10] [15.950718]vhci_hcd 1e6a0000.usb-vhub: ASpeed Virtual Hub
[20250312-15:04:10] [15.950747]vhci_hcd 1e6a0000.usb-vhub: new UsB bus registered, assigned bus number 4
[20250312-15:04:10][15.970205] 1bf20: 805d8340 00000000 b106bf44 b106bf38 80439084 80438e70 b106bf6c b106bf48
[20250312-15:04:10][15.972306]gpio_ast1530 4f84c000.gpio: ast_gpio_set_debounce: Pin 6: debounce 1000choose 2-timer
[20250312-15:04:10][15.972384]insmod:vhub_hal_initialization(4701) : HUB plugged
[20250312-15:04:10][15.972712]usb usb4: New USB device found, idVendor=ld6b, idProduc

从上述日志发现出现内核panic,但是下面又出现了usb的日志,可以将usb驱动不进行加载,排除该问题。再从日志上发现报错在at_unix_insert_socket这个函数,但是这个函数不在某个驱动中,也不知道是哪个驱动发生了错误。因此,我们可以依据cp指针 借助内核编译生成的.vmlinux找到出问题的位置

xxx-addr2line -e ./vmlinux 0x804375ac

如果出现在某个.h 或者内核代码中,可以先排除是否是内核版本太旧导致的问题

二、局部变量的作用域问题

    struct i2c_manager i2c_mgr;

    LOG_DEBUG("zzl%s:%d\n", __func__, __LINE__);

    alps_data = (struct stk6a7x_data *)kmalloc(sizeof(struct stk6a7x_data), GFP_KERNEL);
    if (!alps_data)
    {
        LOG_ERR("failed to allocate struct stk6a7x_data");
        return -ENOMEM;
    }

    plat_data = (struct stk6a7x_platform_data *)kmalloc(sizeof(struct stk6a7x_platform_data), GFP_KERNEL);
    if (!plat_data)
    {
        LOG_ERR("failed to allocate struct stk6a7x_platform_data");
        goto release_alps_data;
    }

    si2c_new_device(&curr_type->i2c_t->i2c_client, curr_type->i2c_t->bus_num, *curr_type->i2c_t->i2c_boardinfo);

    alps_data->bops = &stk_i2c_bops;
    alps_data->tops = &stk_t_ops;

    memset(&i2c_mgr, 0, sizeof(struct i2c_manager));
    i2c_mgr.addr_type = ADDR_8BIT;
    i2c_mgr.client = curr_type->i2c_t->i2c_client;
    mutex_init(&i2c_mgr.lock);

    alps_data->bus_idx = alps_data->bops->init(&i2c_mgr);

init的实现

struct i2c_manager *pi2c_mgr[MAX_I2C_MANAGER_NUM] = {NULL};

int i2c_init(void* st)
{
    int i2c_idx = 0;

    if (!st)
    {
        return -1;
    }

    for (i2c_idx = 0; i2c_idx < MAX_I2C_MANAGER_NUM; i2c_idx ++)
    {
        if (pi2c_mgr[i2c_idx] == (struct i2c_manager*)st)
        {
            printk(KERN_ERR "%s: i2c is exist\n", __func__);
            return i2c_idx;
        }
        else if (pi2c_mgr[i2c_idx] == NULL)
        {
            pi2c_mgr[i2c_idx] = (struct i2c_manager*)st;
            return i2c_idx;
        }
    }

    return -1;
}

这时i2c_mgr局部结构体变量已经释放了内存,因此如果有使用到全局数组pi2c_mgr的存在概率性panic,如下函数即会出现概率性panic


int i2c_reg_read(int i2c_idx, unsigned int reg, unsigned char *val)
{
    int error = 0;
    struct i2c_manager *_pi2c;
    I2C_REG_ADDR_TYPE addr_type;
    
    STK_ERR("zzl@%s:%d i2c_idx:%d\n", __FUNCTION__, __LINE__, i2c_idx);

    _pi2c = pi2c_mgr[i2c_idx];
    if(_pi2c == NULL)
    {
        STK_ERR("zzl@%s:%d error!\n", __FUNCTION__, __LINE__);
        return -EFAULT;
    }

    STK_ERR("zzl@%s:%d i2c_idx:%d _pi2c->addr_type:%p\n", __FUNCTION__, __LINE__, i2c_idx, &_pi2c->addr_type);

    addr_type = _pi2c->addr_type;

    STK_ERR("zzl@%s:%d reg:0x%x val:%p\n", __FUNCTION__, __LINE__, reg, val);
    mutex_lock(&_pi2c->lock);
    STK_ERR("zzl@%s:%d\n", __FUNCTION__, __LINE__);

    if (addr_type == ADDR_8BIT)
    {
        unsigned char reg_ = (unsigned char)(reg & 0xFF);
        STK_ERR("zzl@%s:%d\n", __FUNCTION__, __LINE__);
        error = i2c_smbus_read_byte_data(_pi2c->client, reg_);
        if (error < 0)
        {
            STK_ERR("%s: fai
[  379.834677][  T667] Unable to handle kernel paging request at virtual address ffffffc02279b9e8
[  379.843348][  T667] Mem abort info:
[  379.846878][  T667]   ESR = 0x96000007
[  379.850670][  T667]   EC = 0x25: DABT (current EL), IL = 32 bits
[  379.856725][  T667]   SET = 0, FnV = 0
[  379.860514][  T667]   EA = 0, S1PTW = 0
[  379.864397][  T667]   FSC = 0x07: level 3 translation fault
[  379.870014][  T667] Data abort info:
[  379.873642][  T667]   ISV = 0, ISS = 0x00000007
[  379.878221][  T667]   CM = 0, WnR = 0
[  379.881924][  T667] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000042939000
[  379.889353][  T667] [ffffffc02279b9e8] pgd=1000000043a43003, p4d=1000000043a43003, pud=1000000043a43003, pmd=100000008ade0003, pte=0000000000000000
[  379.902639][  T667] Internal error: Oops: 0000000096000007 [#1] PREEMPT SMP
[  379.909672][  T667] Skip md ftrace buffer dump for: 0x1609e0
[  379.915341][  T667] Modules linked in: phyparam(OE) swt6652_wifi(OE) skw_sdio_
[  380.369945][  T667] Hardware name: Qualcomm Technologies, Inc. BENGAL IDP nopmi (DT)
[  380.377694][  T667] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  380.385358][  T667] pc : i2c_reg_read+0xd4/0x1dc [phyparam]
[  380.390987][  T667] lr : i2c_reg_read+0xb4/0x1dc [phyparam]
[  380.396604][  T667] sp : ffffffc009e6bb50
[  380.400619][  T667] x29: ffffffc009e6bb50 x28: ffffff804c433e80 x27: 0000000000000000
[  380.408467][  T667] x26: ffffffef6770c0b0 x25: 0000000000000000 x24: 0000000000000007
[  380.416311][  T667] x23: ffffffc02279b990 x22: ffffffef65a46cfc x21: 0000000000000000
[  380.424150][  T667] x20: 0000000000000004 x19: ffffffc009e6bb94 x18: ffffffc009a7d068
[  380.431988][  T667] x17: ffffffffffffffff x16: 0000000000000004 x15: 0000000000000004
[  380.439841][  T667] x14: ffffffef68bface0 x13: 00000000000003b7 x12: 0000000000000001
[  380.447700][  T667] x11: 0000000000000000 x10: 0000000000000001 x9 : 07a759925ba5f300
[  380.455541][  T6
[  380.463386][  T667] x5 : 0000000000000004 x4 : 0000000000000052 x3 : ffffffef65a46cfc
[  380.471231][  T667] x2 : 0000000000000052 x1 : ffffffef65a46cfc x0 : ffffffef65a466cf
[  380.479077][  T667] Call trace:
[  380.482227][  T667]  i2c_reg_read+0xd4/0x1dc [phyparam]
[  380.487508][  T667]  i2c_reg_read_modify_write+0x110/0x200 [phyparam]

三、linux内存申请

kmalloc 申请内存,但是不会对内存清零,因为其是从slab里拿一块旧内存,不清零,原来是谁用过、写过什么,不清楚
kzalloc 申请内存,会对内存进行清零操作

四、编译指令添加-v参数

arm-linux-gnueabihf-gcc main.c -o main -pthread -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/4.9.4/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: /home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/snapshots/gcc-linaro-4.9-2017.01/configure SHELL=/bin/bash --with-mpc=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-mpfr=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gmp=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gnu-as --with-gnu-ld --disable-libmudflap --enable-lto --enable-objc-gc --enable-shared --without-included-gettext --enable-nls --disable-sjlj-exceptions --enable-gnu-unique-object --enable-linker-build-id --disable-libstdcxx-pch --enable-c99 --enable-clocale=gnu --enable-libstdcxx-debug --enable-long-long --with-cloog=no --with-ppl=no --with-isl=no --disable-multilib --with-float=hard --with-mode=thumb --with-tune=cortex-a9 --with-arch=armv7-a --with-fpu=vfpv3-d16 --enable-threads=posix --enable-multiarch --enable-libstdcxx-time=yes --with-build-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/sysroots/arm-linux-gnueabihf --with-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/libc --enable-checking=release --disable-bootstrap --enable-languages=c,c++,fortran,lto --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf --prefix=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg-build/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu
Thread model: posix
gcc version 4.9.4 (Linaro GCC 4.9-2017.01) 
COLLECT_GCC_OPTIONS='-o' 'main' '-pthread' '-v' '-march=armv7-a' '-mtune=cortex-a9' '-mfloat-abi=hard' '-mfpu=vfpv3-d16' '-mthumb' '-mtls-dialect=gnu'
 /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/4.9.4/cc1 -quiet -v -imultilib . -imultiarch arm-linux-gnueabihf -iprefix /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/ -isysroot /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc -D_REENTRANT main.c -quiet -dumpbase main.c -march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard -mfpu=vfpv3-d16 -mthumb -mtls-dialect=gnu -auxbase main -version -o /tmp/ccwupN6d.s
GNU C (Linaro GCC 4.9-2017.01) version 4.9.4 (arm-linux-gnueabihf)
        compiled by GNU C version 4.8.4, GMP version 6.0.0, MPFR version 3.1.3, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/../../lib/gcc/arm-linux-gnueabihf/4.9.4/include"
ignoring nonexistent directory "/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/local/include/arm-linux-gnueabihf"
ignoring nonexistent directory "/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/local/include"
ignoring duplicate directory "/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/../../lib/gcc/arm-linux-gnueabihf/4.9.4/include-fixed"
ignoring duplicate directory "/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/../../lib/gcc/arm-linux-gnueabihf/4.9.4/../../../../arm-linux-gnueabihf/include"
ignoring nonexistent directory "/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/include/arm-linux-gnueabihf"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/include
 /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/include-fixed
 /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/../../../../arm-linux-gnueabihf/include
 /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/include
End of search list.
GNU C (Linaro GCC 4.9-2017.01) version 4.9.4 (arm-linux-gnueabihf)
        compiled by GNU C version 4.8.4, GMP version 6.0.0, MPFR version 3.1.3, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 2f906073d57f32bb591416a2139d1491
COLLECT_GCC_OPTIONS='-o' 'main' '-pthread' '-v' '-march=armv7-a' '-mtune=cortex-a9' '-mfloat-abi=hard' '-mfpu=vfpv3-d16' '-mthumb' '-mtls-dialect=gnu'
 /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/../../../../arm-linux-gnueabihf/bin/as -v -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -meabi=5 -o /tmp/ccVCLy6b.o /tmp/ccwupN6d.s
GNU assembler version 2.24.0 (arm-linux-gnueabihf) using BFD version (Linaro_Binutils-2017.01) 2.24.0.20141017 Linaro 2014_11-3-git
COMPILER_PATH=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/4.9.4/:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../libexec/gcc/:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/../../../../arm-linux-gnueabihf/bin/
LIBRARY_PATH=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/../../../../arm-linux-gnueabihf/lib/:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/lib/:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/lib/
COLLECT_GCC_OPTIONS='-o' 'main' '-pthread' '-v' '-march=armv7-a' '-mtune=cortex-a9' '-mfloat-abi=hard' '-mfpu=vfpv3-d16' '-mthumb' '-mtls-dialect=gnu'
 /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/4.9.4/collect2 -plugin /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/4.9.4/liblto_plugin.so -plugin-opt=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/4.9.4/lto-wrapper -plugin-opt=-fresolution=/tmp/ccWZi7gd.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc --build-id --eh-frame-hdr -dynamic-linker /lib/ld-linux-armhf.so.3 -X -m armelf_linux_eabi -o main /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/lib/crt1.o /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/lib/crti.o /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/crtbegin.o -L/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4 -L/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf -L/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc -L/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/../../../../arm-linux-gnueabihf/lib -L/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/lib -L/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/lib /tmp/ccVCLy6b.o -lgcc --as-needed -lgcc_s --no-as-needed -lpthread -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/crtend.o /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/lib/crtn.o

从上述的编译打印出来的详细信息可得到:
1、工具链的安装目录

/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/

后续该目录统一使用$PREFIX
2、各阶段可执行程序位置

阶段实际调用路径
编译器驱动$PREFIX/bin/arm-linux-gnueabihf-gcc
c编译器(cc1)$PREFIX/libexec/gcc/arm-linux-gnueabihf/4.9.4/cc1
汇编器(as)$PREFIX/bin/arm-linux-gnueabihf-gcc/as
连接器(collect2)$PREFIX/libexec/gcc/arm-linux-gnueabihf/4.9.4/collect2
LTO插件$PREFIX/libexec/gcc/arm-linux-gnueabihf/4.9.4/liblto_plugin.so

3、目标系统根目录

$PREFIX/arm-linux-gnueabihf/libc

所有目标头文件、库、启动文件都以此为**/** 根
4、头文件搜索顺序(编译阶段)

#include "..." 搜索起点: 当前目录
#include <...> 搜索目录列表:
  1. $PREFIX/lib/gcc/arm-linux-gnueabihf/4.9.4/include
  2. $PREFIX/lib/gcc/arm-linux-gnueabihf/4.9.4/include-fixed
  3. $PREFIX/arm-linux-gnueabihf/include
  4. $PREFIX/arm-linux-gnueabihf/libc/usr/include

5、库文件搜索路径(LIBRARY_PATH,链接阶段)

1. $PREFIX/lib/gcc/arm-linux-gnueabihf/4.9.4/
2. $PREFIX/lib/gcc/arm-linux-gnueabihf/
3. $PREFIX/lib/gcc/
4. $PREFIX/arm-linux-gnueabihf/lib/
5. $PREFIX/arm-linux-gnueabihf/libc/lib/
6. $PREFIX/arm-linux-gnueabihf/libc/usr/lib/

6、启动文件与动态链接器
启动文件(按顺序):

$PREFIX/arm-linux-gnueabihf/libc/usr/lib/crt1.o
$PREFIX/arm-linux-gnueabihf/libc/usr/lib/crti.o
$PREFIX/lib/gcc/arm-linux-gnueabihf/4.9.4/crtbegin.o
$PREFIX/lib/gcc/arm-linux-gnueabihf/4.9.4/crtend.o
$PREFIX/arm-linux-gnueabihf/libc/usr/lib/crtn.o

动态链接器(程序运行时使用):

/lib/ld-linux-armhf.so.3(在目标系统内)

五、ldd指令

ldd指令是Linux、Android下一个非常经典的动态库分析工具,
作用是查看程序运行时依赖哪些.so 库文件

:/ # ldd /phone/boot/bin/bootctl                                                                            
        linux-vdso.so.1 => [vdso] (0x731201c000)
        libhidlbase.so => /system/lib64/libhidlbase.so (0x730d85d000)
        libhidltransport.so => /system/lib64/libhidltransport.so (0x730d7e6000)
        libhwbinder.so => /system/lib64/libhwbinder.so (0x7310cca000)
        libutils.so => /system/lib64/libutils.so (0x730d71b000)
        android.hardware.boot@1.0.so => /system/lib64/android.hardware.boot@1.0.so (0x7310d5e000)
        libc++.so => /system/lib64/libc++.so (0x730d916000)
        libc.so => /apex/com.android.runtime/lib64/bionic/libc.so (0x730b489000)
        libm.so => /apex/com.android.runtime/lib64/bionic/libm.so (0x730d806000)
        libdl.so => /apex/com.android.runtime/lib64/bionic/libdl.so (0x7310cb2000)
        libbase.so => /system/lib64/libbase.so (0x7310d01000)
        liblog.so => /system/lib64/liblog.so (0x730d6cb000)
        libcutils.so => /system/lib64/libcutils.so (0x730d79d000)
        libvndksupport.so => /system/lib64/libvndksupport.so (0x7310c62000)
        libdl_android.so => /apex/com.android.runtime/lib64/bionic/libdl_android.so (0x730d747000)

ldd库可以展示出其依赖的多级库文件,因为可能存在部分.so依赖与其他.so

六、readelf指令

先了解elf是什么?Linux/Android可执行文件,内部大概为

ELF Header
Program Header
Section Header
.text
.data
.dynamic
.got
.plt
...

其中.dynamic就是动态链接信息区, 可使用readelf读出可执行文件该区域的内容:

:/ # readelf -d /phone/boot/bin/bootctl                                                                     

Dynamic section at offset 0xfc80 contains 40 entries:
  Tag                Type                 Name/Value
 0x0000000000000003 (PLTGOT)             0x1ff20
 0x0000000000000002 (PLTRELSZ)           600 (bytes)
 0x0000000000000017 (JMPREL)             0xd38
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000007 (RELA)               0x9a8
 0x0000000000000008 (RELASZ)             912 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffff9 (RELACOUNT)          36
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000006 (SYMTAB)             0x288
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000005 (STRTAB)             0x588
 0x000000000000000a (STRSZ)              909 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x918
 0x0000000000000001 (NEEDED)             Shared library: [libhidlbase.so]
 0x0000000000000001 (NEEDED)             Shared library: [libhidltransport.so]
 0x0000000000000001 (NEEDED)             Shared library: [libhwbinder.so]
 0x0000000000000001 (NEEDED)             Shared library: [libutils.so]
 0x0000000000000001 (NEEDED)             Shared library: [android.hardware.boot@1.0.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc++.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so]
 0x0000000000000020 (PREINIT_ARRAY)      0x1fae8
 0x0000000000000021 (PREINIT_ARRAYSZ)    0x10
 0x0000000000000019 (INIT_ARRAY)         0x1faf8
 0x000000000000001b (INIT_ARRAYSZ)       16 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x1fb08
 0x000000000000001c (FINI_ARRAYSZ)       16 (bytes)
 0x000000000000001e (FLAGS)              BIND_NOW
 0x000000006ffffffb (FLAGS_1)            Flags: NOW
 0x000000006ffffff0 (VERSYM)             0x948
 0x000000006ffffffe (VERNEED)            0x988
 0x000000006fffffff (VERNEEDNUM)         1
 0x0000000000000000 (NULL)               0x0
 0x0000000000000000 (NULL)               0x0
 0x0000000000000000 (NULL)               0x0
 0x0000000000000000 (NULL)               0x0
 0x0000000000000000 (NULL)               0x0
 0x0000000000000000 (NULL)               0x0
 或者使用
 readelf -d /phone/boot/bin/bootctl  | grep NEEDED
 :/ # readelf -d /phone/boot/bin/bootctl  | grep NEEDED                                                      
 0x0000000000000001 (NEEDED)             Shared library: [libhidlbase.so]
 0x0000000000000001 (NEEDED)             Shared library: [libhidltransport.so]
 0x0000000000000001 (NEEDED)             Shared library: [libhwbinder.so]
 0x0000000000000001 (NEEDED)             Shared library: [libutils.so]
 0x0000000000000001 (NEEDED)             Shared library: [android.hardware.boot@1.0.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc++.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so]

注意:使用ldd会更深入,readelf只是把可执行文件内部申明的依赖列出,ldd会把程序所需要运行所有库文件列出,包括二级依赖

Linux的gdb调试 Debug 版本为可调式版本,生成的可执行文件中包含调试需要的信息。我们作为开发人员,最常用的就是 debug 版本的可执行文件。Debug 版本的生成:因为调试信息是在编译过程时加入到中间文件(.o)中的,所以必须在编译时控制其生成包含调试信息的中间文件。所以debug版本的体积要大一些。gcc -c hello.c -g —> 生成包含调试信息的中间文件或者。 阅读详情

相关推荐

Linux GDB调试器

Linux GDB调试器基础概念调试工具的优缺点gdb调试器的使用过程调试命令 基础概念 bug : 计算机软硬件行业描述坏点,异常,错误。 Debug : Debug调试器用于查找程序中的错误。 调试工具的优缺点 GUI调试工具 : 可视化调试器。 优点:容易使用,对用户较为友好 缺点:开销大,效率低 GDB调试工具 : 命令行调试器。 优点:资源占用小,速度快,多程序同步调不会产生冲突 缺点:使用较为麻烦 gdb调试器的使用过程 1 . gcc ***.c -g -o app 2 . gdb app

weixin_43811333的博客 577

linux网卡phy地址修改,【基础技能】Linux PHY驱动调试方法

https://gitee.com/lee790608/linuxPhyDriverSTEP1 准备硬件环境1. 开发环境,可以修改内核代码,编译2. 硬件开发板,可以进入系统调试,可以传送代码(常用的ADB打通即可)3. PHY芯片,最好是贴在开发板上,如果飞线,对走线信号要求非常高(尤其是SGMII)4. 示波器,方便抓取MDIO / SGMII总线信号STEP2 获取VDD和VDDIO,修改...

weixin_39907220的博客 2046

Linux下程序调试的方法【GDB】GDB相关命令和基础操作(命令收藏)

g选项的作用是在可执行文件中加入源代码的倍息,比如可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb能找到源文件。简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式,⽐如当前正在调试C语⾔的程序,那么“表达式”可以是任何C语⾔的有效表达式,包括数字,变量甚⾄是函数调⽤。在文件名为filename的原文件的名为function的函数上设置断点。设置⼀个监视点,⼀旦被监视的“表达式”的值改变,gdb将强⾏终⽌正在被调试的程序。

吻等离子的博客 684

c/c++基础(二十七) Linux下core文件调试方法

在程序开发中,我们常常用多种方法来定位程序的异常退出,如:打印日志,gdb core等. 在程序不寻常退出时,内核会在当前工作目录下生成一个core文件(是一个内存映像,同时加上调试信息)。使用gdb来查看core文件,可以指示出导致程序出错的代码所在文件和行数。 1.core文件的生成开关和大小限制  1)使用ulimit -c命令可查看core文件的生成开关。若结果为0,

if(...){...} 1052

【linux系统调试】GDB 工具使用与调试方法大全,看这篇就够了

‌ GDB 工具是最常见的调试工具,也是平常工作中使用频率最高最广为人知的嵌入式Linux产品软件调试工具。要想使用该工具进行代码调试,首先需要在编译程序时需添加-g选项保留调试信息。这是前提,否则无法进行后续操作。话不多说,直接进入正题。

以实战经验介绍行业知识 1804

在F1C100s上跑GBA游戏:手把手教你用Buildroot配置SDL和移植gpsp模拟器

本文详细介绍了在全志F1C100s开发板上配置Buildroot、移植SDL库和gpsp模拟器的完整流程,帮助开发者实现在ARM9平台上流畅运行GBA游戏。内容涵盖环境配置、交叉编译、常见问题解决及性能优化技巧,特别针对'段错误'和'无声音'等典型问题提供实用解决方案。

weixin_42566424的博客 398

linux内核调试指南

 linux内核调试指南一些前言作者前言知识从哪里来为什么撰写本文档为什么需要汇编级调试***第一部分:基础知识***总纲:内核世界的陷阱源码阅读的陷阱代码调试的陷阱原理理解的陷阱建立调试环境发行版的选择和安装安装交叉编译工具bin工具

Hunnad的专栏 2万+

加法器设计—— 原理图与VHDL设计初步

1、在DE2-115开发板上,完成4位全加器系统的设计、下载和功能演示,并在FPGA上实现1位全加器;2、完成3-8译码器的设计、下载和功能演示(利用板上的8段数码管)本次实验在组合逻辑电路的基础上,运用Verilog编程实现了四位全加器和3-8译码器的设计,同时实现了在DE2-115开发板上的下载和功能演示。整个过程加深了我对电路设计和Verilog编程的理解,同时也锻炼了解决问题的能力。

m0_74749526的博客 1237

【Linux指南】Linux调试利器gdb入门:从编译到基础命令实战

在Linux环境下开发C/C++程序时,遇到bug是家常便饭。无论是逻辑错误、内存泄漏还是运行时崩溃,一款强大的调试工具都能帮我们快速定位问题根源。gdb(GNU Debugger) 作为Linux系统中最常用的命令行调试工具,支持断点设置、变量查看、单步执行等核心功能,是开发者排查问题的"利器"。 本文将从最基础的"如何生成可调试程序"讲起,逐步介绍gdb的启动方式、核心调试命令及实战技巧,帮助新手快速掌握gdb的使用方法。

倔强的石头的博客 7099

LVGL 实战:虚拟列表与对象复用机制在嵌入式GUI中的性能优化

本文深入探讨LVGL虚拟列表与对象复用机制在嵌入式GUI中的性能优化实践。通过复用机制动态管理UI对象,大幅降低内存占用,实现无限滚动列表的流畅体验。文章详细解析核心算法、内存优化策略及跨平台适配技巧,帮助开发者在资源受限设备上高效处理大量数据展示。

rice5的博客 1106

CST新手必看:共面波导色散曲线绘制全流程(附参数设置避坑指南)

本文详细介绍了CST Microwave Studio中绘制共面波导色散曲线的全流程操作,特别针对新手常见的边界条件设置错误、参数扫描失效等问题提供解决方案。通过模型建立、边界条件设置、本征模求解器配置等步骤,帮助工程师快速掌握CPW色散特性分析方法,并附有参数设置避坑指南,提升高频电路设计效率。

tomato的博客 990

Linux调试器---gdb的使用

GDB,全称为GNU调试器(GNU Debugger),是一个功能强大的源代码级调试工具,主要应用于Unix系统,以及Linux下的程序开发

顾得泉的博客 2017

MATLAB - 使用 RRT 进行挖掘机运动规划

本例演示了如何使用运动规划器在包含障碍物的环境中为挖掘机规划路径。在此示例中,您将以运动树的简化形式为挖掘机建模,然后使用基于采样的运动规划器确定挖掘机在存在障碍物的两个姿势之间的可行路径。在 Simscape™ 多体™ 模型中模拟结果。

机器人控制与仿真应用 1850

【Linux入门】shell基础篇——shell的构成及基础调试

Shell(外壳)是在 Linux/Unix 系统中用于与操作系统进行交互的一种命令行界面。它允许用户通过键入文本命令来执行各种任务,如文件操作、程序运行、设备管理等。Shell 不仅允许用户直接输入命令执行,还可以通过 Shell 脚本将多个命令组合起来,实现更复杂的自动化任务。简而言之就是给要执行的命令按照顺序保存到一个文本文件中,然后给文件可执行权限,可以结合shell控制语句完成更复杂的操作。Shell 的主要功能包括:命令执行:用户可以在 Shell 中输入命令,系统会解释并执行这些命令。

Karoku的博客 1588

083、多帧降噪(MFR)与VST算法:低照度场景下的信噪比提升与鬼影抑制

本文深入探讨了多帧降噪(MFR)和VST算法在低照度场景中的应用与优化。作者从实际项目案例出发,指出单帧降噪的局限性,详细分析了MFR的核心原理与工程实现中的关键环节,包括帧对齐、帧选择、融合策略和鬼影抑制等技术要点。文章特别强调VST变换对噪声均匀化的重要性,并分享了实际开发中的调试经验与参数优化技巧,如"三明治"调试法和性能平衡策略。最后指出,优秀的MFR方案需要在信噪比提升、鬼影抑制和纹理保留之间找到场景化的平衡点,建议开发者通过真实场景测试验证算法效果。全文既有理论分析,又包含丰富的实战经验和技术细

zzfmlxs的博客 123

planning模块(6)-参考线的平滑(二次规划)

上一篇已经介绍了采样点生成锚点数据的过程,并且将所有采样点生成的锚点数据设置到了平滑器中.接下来继续介绍使用二次规划平滑参考线的算法过程.从锚点数据中提取坐标存入raw_point2d,提取横向边界存入anchorpoints_lateralbound,将起点和终点的横向边界设置为0,防止车在起点和终点位置偏离车道中心线.

让复杂的问题变得更容易理解 788

Linux后台开发系列之「08.15 个 gdb 调试基础命令」

代码键盘 版权声明:本文为 cdeveloper 原创文章,可以随意转载,但必须在明确位置注明出处! gdb 简介 gdb是UNIX及UNIX-like下的调试工具,在 Linux 下一般都直接在命令行中用 gdb 来调试程序,相比 Windows 上的集成开发环境IDE提供的图形界面调试,一开始使用 gdb 调试可能会让你感到生无可恋,但是只要熟悉了 gdb 调试的常...

Linuxhus的博客 282

Unity-TextMeshPro如何扩展材质实现字体Face+Outline流光效果

前言 TexeMeshPro 是Unity的一个Text文本插件,实现了比UGUI的Text,更好看的效果,跟高效的性能,所以深受大家的喜欢,但是再好的插件,也不是万能的,比如我们的策划有个新需求,要我们的VIP的名字比普通玩家有更好看的效果,例如:字体流光,外发光颜色扰动,字体贴图等等。那我们就需要去扩展TextMeshPRo的shader功能了。如下图所示 本文,我就带大家一起来扩展一下:如何扩展TextMeshProUGUI TextMesh原始面板 扩展功能后的面板 扩展TextMeshPro

TxNet 9676

linux 内核调试指南

linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 建立调试环境 发行版的选择和安装 安装交叉编译工具 bin工具集的使用 qemu的使用

djinglan的专栏 1万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

linux打开core文件,Linux下调试core dump 文件的方法

在开发和使用Linux 程序时,引擎有时会莫名其妙的core 掉,在网上查了一下,整理了一个简单的调试core 文件的方法。1、什么是core dump?Core,即core memory,而dump 就是堆放的意思。core dump 又叫核心转储,当程序运行过程中发生异常,程序异常退出时,由操作系统把程序当前的内存状况存储在一个core 文件中,叫core dump。2、如何打开core du...

weixin_29279047的博客 738

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

linux下如何调试c语言代码_Linux下gdb调试与技巧整理

目录 一、gdb简介 二、gdb使用流程 1、启动gdb 2、查看源码 3、运行程序 4、设置断点 5、单步执行 6、查看变量 7、退出gdb 三、gdb基本使用命令 1、运行命令 2、设置断点 3、查看源码 4、打印表达式 ...

weixin_39566882的博客 391

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Linux调试神器 -- gdb

一:起因 (1)也许我们非常熟悉Windows下的VC6.0 和 CodeBlocks的调试工具 —— 界面化的调试,但是你是否想过你的每一个按键或者快捷键的背后指令是什么,让我们一起走进Linux的gcc动态调试工具GDB (2)程序调试无非就是:debug(gcc -g -o target source);设置断点(b n);观察变脸(info locals);观察特定值(print ex

思緒凌亂 6864

linux 内核性能调试分析

调试内核模块性能需要特殊工具和方法,因为模块运行在内核空间,直接影响系统稳定性。

zly8865372的博客 855

【Linux系统】GDB 调试完全指南:从基础到进阶,解决 90% 的 C/C++ 调试问题

本文介绍了GDB调试工具的核心使用方法。基础部分包括编译配置(-g选项)、常用命令(断点设置、变量查看、单步执行等)和常见问题解决方案。进阶部分讲解了条件断点、观察点等高级调试技巧,帮助定位复杂问题。文章还总结了GDB调试的核心工作流程,从编译启动到问题定位的全过程。掌握这些内容可以解决大多数C/C++程序的调试需求,如需更深入功能可参考官方文档。全文提供了实用的调试技巧和常见问题应对方案,是GDB调试的实用指南。

HZzzzzLu的博客 1454
上一篇: ESP-IDF开发 ------ esp32_s3拿到手使用usb-otg口无法下载
下一篇: 【linux】clang和clangd之间区别
菜菜小志
博客等级 码龄6年 1705粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值