GDK7+NanoCode调试学习系列5--调试Ubuntu应用程序

前几篇都是讲述了使用GDK7和NanoCode来调试内核的方法,请参考“GDK7+NanoCode调试学习系列”(https://blog.csdn.net/henly1217/category_10244945.html

本篇继续学习:

    - 使用NanoCode来远程调试目标机GDK7的应用程序

    - 分别通过“附加到进程”和“创建新进程”的方式来调试

注:

1. 请将主机和目标机连接在同一个局域网内。

2. 由于受限于tty进制,通过“创建新进程”的方式无法调试交互式或者带UI的程序。(本篇调试自己编译的readelf程序)

 

准备工作:

1. 目标价GDK7需要使用新版本的ndsrv模块,请至http://advdbg.org/gdk/resource.aspx下载新版本,安装到目标机(使用systemctl status | grep ndsrv 查询服务是否在运行);

2. 主机NanoCode需要使用1.1.0或以上版本;

3. 准备被调试的程序(如果没有,这里使用了一个简单c++程序来调试,请复制出来保存到main.cpp,然后编译:g++ -g main.cpp -o main),请使用-g编译,带调试信息。

4. 将执行程序main复制在目标机上,

5. 同时将main放置在主机c:\temp\app下(目录可换),main.cpp放置在主机d:\dbg-source\main下(目录可换),用于解析符号和定位源代码。

#include <stdio.h>

#include <iostream>
#include <string>
#include <vector>

int sub(int a, int b) {
   return a - b;
}

int add(int a, int b) {
   return a + b;
}

void split_string(const std::string& input, char splitter, std::vector<std::string>& vec){
	vec.clear();

	if(input.empty())
		return;

	std::string::size_type begin = 0, pos =input.find(splitter);
	while(pos != std::string::npos){
		std::string tmp = input.substr(begin, pos - begin);
		if(!tmp.empty()){
			vec.push_back(tmp);
		}

		begin = pos + 1;
		pos = input.find(splitter, begin);
	}

	if(begin < input.size()){
		vec.push_back(input.substr(begin));
	}
}

void usage() {
	std::cout << "Usage:" << std::endl;
	std::cout << "q - Exit app" << std::endl;
	std::cout << "h - Show usage" << std::endl;
	std::cout << "sub - Execute sub(a, b) function" << std::endl;
	std::cout << "add - Execute add(a, b) function" << std::endl;
}

static const char* s_ver = "1.0";
int main() {
	std::cout << "c++ example version:" << s_ver << std::endl;
	usage();

	int result = 0;
    
	std::string input;
	std::vector<std::string> vec;
    for(; ;) {
        std::cout << "Please input commnd:";
        getline(std::cin, input);

		split_string(input, ' ', vec);
        if(vec[0] == "q"){
        	break;
        } else if(vec[0] == "h"){
			usage();
		}else if (vec[0] == "add"){
			if(vec.size() < 3){
				std::cout << "Err: less paramter(add x y)" << std::endl;
				continue;
			}
			int x = atoi(vec[1].c_str());
			int y = atoi(vec[2].c_str());
	    	result = add(x, y);
		    std::cout << "Add Result:" << result << std::endl;	
		} else if (vec[0] == "sub"){
			if(vec.size() < 3){
				std::cout << "Err: less paramter(sub x y)" << std::endl;
				continue;
			}
			int x = atoi(vec[1].c_str());
			int y= atoi(vec[2].c_str());
	    	result = sub(x, y);
			std::cout << "Sub Result:" << result << std::endl;	
		} else {
			std::cout << "Err: Unknown command:" << vec[0] << std::endl;		
			usage();
		}       
    }

	std::cout << "App exits, bye." << std::endl;
    return 0;
}

开始调试:

调试正在运行的进程

1. 查看目标机ip地址;

1. 在目标机控制台启动main程序,显示如下:

ubuntu

2. 在主机端启动NanoCode;

3. 在NanoCode里设置目标机的ip和port,并且连接到目标机(如果没有连接成功,将会报错),操作如下:

输入(tcp:port=200,server=目标ip)端口固定,点击“Connect”;

conn remote

4. 在NanoCode里选择被调试的远程程序,操作如下:

conn remote exe

5. 至此,已经挂上并中断下远端Ubuntu的main程序了;

break

6. 此时,main程序已被挂起;

7. 下面,开始设置符号路径和源文件路径;

.sympath+ c:\temp\app

.srcpath+ d:\dbg-source\main

symsrc

8. 查询main的符号

x main!*

可以看出,列出了好多stl的很多符号

xmain

9. 调试main的sub函数

x main!sub // 查找函数地址

bp 地址 // 对函数地址下断点

bpsub

10. 重新g起来;

11. 在目标机main程序下触发sub函数,输入sub 2 1,然后回车,成功断下,并且源代码也自动打开;

break bp

12. 然后可以单步执行,查看寄存器,变量来调试了~~~

dbg

 

调试新创建的进程--调试readelf

1. 下载binutils,从https://ftp.gnu.org/gnu/binutils/下载,在ubuntu上编译,然后将readelf和源码复制一份到主机端,用于解析符号和源码调试 。

2. 主机NanoCode连接到目标机,如上步骤1,重新设置:在NanoCode里设置目标机的ip和port,并且连接到目标机(如果没有连接成功,将会报错)

2. 在NanoCode里File->Open Executable...输入远程程序命令,或者使用历史记录,这里没有带任何参数,readelf打印帮助之后,就会自动退出了。

ceate exe

3. 点击确认,然后设置符合和源码路径

ss

4. 然后查找函数,下断点,我们在main函数下断点

bp main

5. 然后输入g,重新跑起来,程序自动断下,同时源码也自动打开

break main

6. 查看一下寄存器和临时变量

info

7. 至此,可以继续调试其他了。

 

总结:

1. 主要使用NanoCode远程调试Ubuntu上的应用程序;

2. 不足:当调试完一个实例之后,下次调试又需要重新连接一次目标机; 

3. 不足:使用“创建新进程”的方式,暂时无法调试交互式或者带UI的程序; 

4. 待续。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值