当前位置: 首页 > news >正文

php网站开发的第三章个人电脑做网站服务器网站

php网站开发的第三章,个人电脑做网站服务器网站,单本小说网站,微营销推广软件一、背景 qemu单步调试arm64 linux kernel-CSDN博客介绍了如何单步调试kernel#xff0c; 但是我们经常写一些测试driver, driver的部分如何调试#xff1f; 二、环境准备 调试driver 就需要准备一个简单的driver#xff0c; 这里用最简单的hello world来演示如何调试 但是我们经常写一些测试driver, driver的部分如何调试 二、环境准备 调试driver 就需要准备一个简单的driver 这里用最简单的hello world来演示如何调试程序非常简单生成一个字符设备并且在cat的时候打印变量还加了一个全局变量用来gdb调试查看变量使用 #include linux/module.h /* Needed by all modules */ #include linux/kernel.h /* Needed for KERN_INFO */ #include linux/init.h /* Needed for the macros */ #include linux/miscdevice.h /* Needed for misc device */int global_hello_value 996;#define DEVICE_NAME Helloworldvoid test_for_debug(void) { printk(KERN_INFO just for debug the text section %d, global_hello_value); }static int hello_open(struct inode *inode, struct file *file){test_for_debug();return 0; }static struct file_operations hello_fops { .owner THIS_MODULE,.open hello_open, };static struct miscdevice hello_misc { .minor MISC_DYNAMIC_MINOR,.name Helloworld,.fops hello_fops, };static int __init hello_start(void) {int ret;ret misc_register(hello_misc);if (ret 0) {printk(KERN_EMERG %s register failed %d.\n, DEVICE_NAME, ret);return ret;} printk(KERN_INFO Hello world\n); return 0; }static void __exit hello_end(void) { test_for_debug();misc_deregister(hello_misc);printk(KERN_INFO hello_end Goodbye\n); } MODULE_LICENSE(GPL); MODULE_AUTHOR(geek); MODULE_DESCRIPTION(A simple Hello world misc driver!); MODULE_VERSION(0.1);module_init(hello_start); module_exit(hello_end); 编译ko需要使用 make modules指令 make ARCHarm64 CROSS_COMPILEaarch64-none-linux-gnu- modules -j8 编译完成后会在hello driver的源码目录生成对应的ko文件; 将ko 放在我们的rootfs 中参考前一篇 无人知晓qemu搭建arm64 linux kernel调试环境 rootfs image制作部分挂载rootfs.img, 拷贝ko, 然后umount img sudo mount rootfs.img rootfs sudo mkdir rootfs/driver sudo cp ../hello_driver.ko rootfs/driver/ sudo umount rootfs 三、加载ko insmod 加载打印hello world, 同时生成/dev/Helloworld节点 ~ # insmod driver/hello_driver.ko [ 11.203785] Hello world ~ # cd /dev/ /dev # ls Helloworld ptypc tty36 ttyp0 gdb 连接后尝试看下之前ko的global_hello_value变量无法显示test_for_debug函数也是无法找到的 (gdb) p global_hello_value No symbol global_hello_value in current context. (gdb) b test_for_debug Function test_for_debug not defined. Make breakpoint pending on future shared library load? (y or [n]) n 四、调试ko 调试ko的步骤也是分三步先加载ko, 确认ko加载的地址然后加载ko symbols,加载地址需要和实际加载一致 ; 最后一步就是加断点然后启动调试即可 方法1 insmod ko之后根据节点/sys/module/XXXX/sections/ 确认ko 加载的地址 /driver # cat /sys/module/hello_driver/sections/.text 0xffff80007a860000 加载ko symbols gdb 中执行 (gdb) add-symbol-file drivers/my_driver/hello_driver.ko -s .text 0xffff80007a860000 add symbol table from file drivers/my_driver/hello_driver.ko at.text_addr 0xffff80007a860000 (y or n) y Reading symbols from drivers/my_driver/hello_driver.ko... 然后再设置断点 (gdb) b test_for_debug Breakpoint 1 at 0x4: test_for_debug. (3 locations) (gdb) c Continuing. continue 后 qemu中cat节点即可触发中断 /dev # cat Helloworld gdb窗口 (gdb) bt #0 0xffff80007a860004 in test_for_debug () at drivers/my_driver/hello_driver.c:12 #1 hello_open (inode0xffff000002f11610, file0xffff00000381bb00) at drivers/my_driver/hello_driver.c:16 #2 0xffff8000808623d8 in misc_open (inode0xffff000002f11610, file0xffff00000381bb00) at drivers/char/misc.c:165 #3 0xffff8000802c8250 in chrdev_open (inode0xffff000002f11610, filp0xffff00000381bb00) at fs/char_dev.c:414 #4 0xffff8000802bcfcc in do_dentry_open (f0xffff00000381bb00, inode0xffff000002f11610, open0xffff8000802c8194 chrdev_open) at fs/open.c:929 #5 0xffff8000802beda0 in vfs_open (path0x2 hello_end2, file0xffff000002f11610) at fs/open.c:1063 #6 0xffff8000802d6350 in do_open (opoptimized out, fileoptimized out, ndoptimized out) at fs/namei.c:3640 #7 path_openat (nd0xffff800082adbc40, op0x4 hello_end4, flags2055602176) at fs/namei.c:3797 #8 0xffff8000802d706c in do_filp_open (dfd-100, pathname0xffff000002e40000, op0xffff800082adbd74) at fs/namei.c:3824 #9 0xffff8000802bf048 in do_sys_openat2 (dfd-100, filename0x646c error: Cannot access memory at address 0x646c, how0x3 hello_end3) at fs/open.c:1422 #10 0xffff8000802bf388 in do_sys_open (modeoptimized out, flagsoptimized out, filenameoptimized out, dfdoptimized out) at fs/open.c:1437 #11 __do_sys_openat (modeoptimized out, flagsoptimized out, filenameoptimized out, dfdoptimized out) at fs/open.c:1453 #12 __se_sys_openat (modeoptimized out, flagsoptimized out, filenameoptimized out, dfdoptimized out) at fs/open.c:1448 #13 __arm64_sys_openat (regs0xffff80007a860000 hello_open) at fs/open.c:1448 #14 0xffff800080027738 in __invoke_syscall (syscall_fnoptimized out, regsoptimized out) at arch/arm64/kernel/syscall.c:37 #15 invoke_syscall (regs0xffff800082adbeb0, scno58833664, sc_nr2055602176, syscall_table0x2 hello_end2) at arch/arm64/kernel/syscall.c:51 #16 0xffff800080027840 in el0_svc_common (regs0xffff800082adbeb0, scno1, syscall_table0x2 hello_end2, sc_nroptimized out) at arch/arm64/kernel/syscall.c:136 #17 0xffff8000800278fc in do_el0_svc (regs0xffff000002f11610) at arch/arm64/kernel/syscall.c:155 #18 0xffff800081016224 in el0_svc (regs0xffff800082adbeb0) at arch/arm64/kernel/entry-common.c:678 #19 0xffff800081016688 in el0t_64_sync_handler (regs0xffff80007a860000 hello_open) at arch/arm64/kernel/entry-common.c:696 #20 0xffff800080011d4c in el0t_64_sync () at arch/arm64/kernel/entry.S:59 但是还有一个问题查看global_hello_value怎么失败了 (gdb) p global_hello_value Cannot access memory at address 0x288 这是因为前面我加载symbols时没有指定.data段只指定了.text段 退出gdb重新修改ko 加载symbols 指令为.text, .data 等段信息均在/sys/module/hello_driver/sections/ 下 (gdb) add-symbol-file drivers/my_driver/hello_driver.ko -s .text 0xffff80007a860000 -s .data 0xffff80007a862000 add symbol table from file drivers/my_driver/hello_driver.ko at.text_addr 0xffff80007a860000.data_addr 0xffff80007a862000 (y or n) y Reading symbols from drivers/my_driver/hello_driver.ko... (gdb) p global_hello_value $1 996 方法2增加断点在load_module中停住这样可以debug 初始化的部分比如module_init中的函数如果我们驱动在这里有bug,根本没机会生成/sys/module下的driver 段信息 ko加载的可以参考这篇 linux ko模块动态加载源码分析 核心就是在do_init_module 设置断点然后从结构体struct module 提取module加载信息 注意module_init函数在 .init.text 段add-symbol-file 需要加入这个 .init.text 才能在module init设置断点 (gdb)b do_init_module 设置好断点后继续然后加载ko,触发断点后将struct module的段信息及地址信息用gdb 显示出来 (gdb) n 2523 freeinit-init_text mod-mem[MOD_INIT_TEXT].base; (gdb) p *mod-sect_attrs-attrs20 在hello_start 设置断点 (gdb) add-symbol-file drivers/my_driver/hello_driver.ko -s .text 18446603338276798464 -s .init.text 18446603338276823040 -s .data 18446603338276806656 add symbol table from file drivers/my_driver/hello_driver.ko at.text_addr 0xffff80007a860000.init.text_addr 0xffff80007a866000.data_addr 0xffff80007a862000 (y or n) y Reading symbols from drivers/my_driver/hello_driver.ko...(gdb) b hello_start Breakpoint 2 at 0xffff80007a866000: file drivers/my_driver/hello_driver.c, line 34.Thread 2 hit Breakpoint 2, hello_start () at drivers/my_driver/hello_driver.c:34 warning: Source file is more recent than executable. 34 ret misc_register(hello_misc); (gdb) bt #0 hello_start () at drivers/my_driver/hello_driver.c:34 #1 0xffff800080014dbc in do_one_initcall (fn0xffff80007a866000 hello_start) at init/main.c:1232 #2 0xffff800080120d20 in do_init_module (mod0xffff80007a862180) at kernel/module/main.c:2530 #3 0xffff800080122dfc in load_module (info0xffff800082af3ac8, uargs0xffff0000035e9d80 \004, flags0) at kernel/module/main.c:2981 #4 0xffff800080123020 in __do_sys_init_module (umod0x23756d60, len38752, uargs0x5bdf21 ) at kernel/module/main.c:3058 #5 0xffff800080123140 in __se_sys_init_module (uargsoptimized out, lenoptimized out, umodoptimized out) at kernel/module/main.c:3038 #6 __arm64_sys_init_module (regs0x0 hello_end) at kernel/module/main.c:3038 #7 0xffff800080027738 in __invoke_syscall (syscall_fnoptimized out, regsoptimized out) at arch/arm64/kernel/syscall.c:37 #8 invoke_syscall (regs0xffff800082af3eb0, scno56532352, sc_nr0, syscall_table0x0 hello_end) at arch/arm64/kernel/syscall.c:51 #9 0xffff800080027840 in el0_svc_common (regs0xffff800082af3eb0, scno-48, syscall_table0x0 hello_end, sc_nroptimized out) at arch/arm64/kernel/syscall.c:136 #10 0xffff8000800278fc in do_el0_svc (regs0x0 hello_end) at arch/arm64/kernel/syscall.c:155 #11 0xffff800081016224 in el0_svc (regs0xffff800082af3eb0) at arch/arm64/kernel/entry-common.c:678 #12 0xffff800081016688 in el0t_64_sync_handler (regs0x0 hello_end) at arch/arm64/kernel/entry-common.c:696 #13 0xffff800080011d4c in el0t_64_sync () at arch/arm64/kernel/entry.S:595 Backtrace stopped: previous frame identical to this frame (corrupt stack?) 方法3利用vmlinux-gdb.py脚本中的lx-symbols辅助命令 利用gdb脚本加载 也是三步先构建gdb script环境; 去掉gdb 脚本执行限制 ; 调用lx-symbols获取ko加载地址当让script中除了获取lx-symbols外还有很多其他脚本辅助我们调试; 参考https://www.codenong.com/cs105354913/ 构建脚本环境 make ARCHarm64 CROSS_COMPILEaarch64-none-linux-gnu- scripts_gdb 根目录生成vmlinux-gdb.py表示成功 去掉gdb脚本加载限制在~/.config/gdb/gdbinit 中添加set auto-load safe-path / 环境变量 此时在linux source加载vmlinux也会提示这个限制错误及解决方法 添加环境变量后重新启动gdb出现了加载vmlinux-gdb.py脚本的错误 上面的报错原因是因为编译kernel版本中打开了config CONFIG_DEBUG_INFO_REDUCED, 这个会影响gdb script的完整功能在arch/arm64/ configs/defconfig中去掉这个config,重新编辑后加载vmlinux 编译kernel之后记得还需要重新生成下脚本 make ARCHarm64 CROSS_COMPILEaarch64-none-linux-gnu- scripts_gdb (gdb) lx-symbols loading vmlinux scanning for modules in /home/geek/workspace/linux/linux-6.6.1 loading 0xffff80007a860000: /home/geek/workspace/linux/linux-6.6.1/drivers/my_driver/hello_driver.ko 这个指令会自动加载ko symbols, 直接加断点即可调试免去了前面通过 add-symbol-file 设置ko section的繁琐步骤但是如果你是调试驱动 init的部分还是得使用上面的方法2 方法3虽然配置有些麻烦但是vmlinux-gdb.py 提供了非常多的调试功能 apropos lx 可以查看这些调试功能能帮助我们提升调试的效率 (gdb) apropos lx function lx_clk_core_lookup -- Find struct clk_core by name function lx_current -- Return current task. function lx_dentry_name -- Return string of the full path of a dentry. function lx_device_find_by_bus_name -- Find struct device by bus and name (both strings) function lx_device_find_by_class_name -- Find struct device by class and name (both strings) function lx_i_dentry -- Return dentry pointer for inode. function lx_module -- Find module by name and return the module variable. function lx_per_cpu -- Return per-cpu variable. function lx_radix_tree_lookup -- Lookup and return a node from a RadixTree. function lx_rb_first -- Lookup and return a node from an RBTree function lx_rb_last -- Lookup and return a node from an RBTree. function lx_rb_next -- Lookup and return a node from an RBTree. function lx_rb_prev -- Lookup and return a node from an RBTree. function lx_task_by_pid -- Find Linux task by PID and return the task_struct variable. function lx_thread_info -- Calculate Linux thread_info from task variable. function lx_thread_info_by_pid -- Calculate Linux thread_info from task variable found by pid lx-clk-summary -- Print clk tree summary lx-cmdline -- Report the Linux Commandline used in the current kernel. lx-configdump -- Output kernel config to the filename specified as the command lx-cpus -- List CPU status arrays lx-device-list-bus -- Print devices on a bus (or all buses if not specified) lx-device-list-class -- Print devices in a class (or all classes if not specified) lx-device-list-tree -- Print a device and its children recursively lx-dmesg -- Print Linux kernel log buffer. lx-dump-page-owner -- Dump page owner lx-fdtdump -- Output Flattened Device Tree header and dump FDT blob to the filename lx-genpd-summary -- Print genpd summary lx-getmod-by-textaddr -- Look up loaded kernel module by text address. lx-interruptlist -- Print /proc/interrupts lx-iomem -- Identify the IO memory resource locations defined by the kernel lx-ioports -- Identify the IO port resource locations defined by the kernel lx-list-check -- Verify a list consistency lx-lsmod -- List currently loaded modules. lx-mounts -- Report the VFS mounts of the current process namespace. lx-page_address -- struct page to linear mapping address lx-page_to_pfn -- struct page to PFN lx-page_to_phys -- struct page to physical address lx-pfn_to_kaddr -- PFN to kernel address lx-pfn_to_page -- PFN to struct page lx-ps -- Dump Linux tasks. lx-slabinfo -- Show slabinfo lx-slabtrace -- Show specific cache slabtrace lx-sym_to_pfn -- symbol address to PFN lx-symbols -- (Re-)load symbols of Linux kernel and currently loaded modules. lx-timerlist -- Print /proc/timer_list lx-version -- Report the Linux Version of the current kernel. lx-virt_to_page -- virtual address to struct page lx-virt_to_phys -- virtual address to physical address lx-vmallocinfo -- Show vmallocinfo 比如我想要查看所有task的信息执行lx-ps即可如果要看task_struct的详细信息将显示的地址转换成struct task_struct *指针即可显示 比如查看一个进程的进程名 (gdb) p ((struct task_struct*)0xffff000002d68ec0)-comm $6 watchdogd\000\000\000\000\000\000
http://www.pierceye.com/news/17391/

相关文章:

  • 厦门seo公司网站wordpress开启缓存
  • 义乌 网站制作全椒县建设局网站
  • 网站搭建行业天津建设工程信息网上网流程
  • 焦作做网站推广开发商破产了购房者怎么办
  • 移动网站建设作业承德住房和城乡建设局网站关闭了
  • 网站建设 手机网站自己做网站申请域名
  • 宁波网站推广宁波seo教程行业推广
  • 帮人做网站赚钱百度推广要不要建网站
  • 网站集约化建设意义全国企业信用信息
  • 在登录某些网站时输入完账号密码后网页跳转后竟然又回到了登陆界面哪个网站可以做记录视频
  • 做网站需要哪些人才丰台网站关键词优化
  • 河南网站推广优化公司门面网站设计
  • google网站收录门户类网站模板
  • python 建设网站如何建广告网站
  • 论坛网站制作模板logo图案免费
  • 深圳企业网站定制廊坊酒店网站建设
  • 陕西建设网网站集群哪里发布网站开发需求
  • 做网站买什么服务器 便宜在哪里可以学做网站
  • 手机怎么建网站21dove谁做的的网站
  • 网站制作需要多少钱新闻广告运营推广
  • 科技网站建设+长沙青岛网站建设软件
  • 网站建设的ci设计指的是什么成都顶呱呱网站建设
  • 做app的网站有哪些功能seo网站内部优化
  • 网站引导动画怎么做的700个吉祥公司名字
  • 郑州定制网站开发福州网站建设 联系yanktcn 04
  • 白银市建设网站企业年报系统官网入口
  • 可口可乐网站建设目的公司网站域名无法解析
  • 买过域名之前就可以做网站了吗?什么 门户网站
  • 网站设计ai做暧暧小视频网站
  • 湖南平台网站建设找哪家打开连接 wordpress