快速开始
比纯调试器调试工程. 一般步骤是:
1) 不配置或简单配置bdebug.ini
2) 开启比纯调试器
3) build命令编译工程
4) 运行工程
5) 工程抛出例外(崩溃 , 无限循环 , 未知结果 ......)
6) 输入一些调试命令以定位错误代码
7) 发现bug原因
8) 修改代码并再次尝试运行
9) 无bug发现, 用shutdown命令退出比纯调试器
最重要的命令是 "build". 您能使用比纯调试器 "build"命令成功编译工程, 您就能用比纯调试器调试之.
BTR\demo 里有许多带有bug的示例工程。用户可以练习比纯调试器的调试方法技巧。
首先,您需在VS中打开quickstart.sln,把里面的工程都编译成功,然后,您再用比纯调试器编译并调试他们。
1) demo目录: demo\win\helloworld.
2)启动比纯调试器.
启动bd
3)build命令编译demo
build d:\BTR\demo\win\helloworld
4) 启动helloworld.exe
cd d:\BTR\demo\win\helloworld\debug
helloworld.exe
5) 程序崩溃.
6) 在bd命令提示符下
flash -s a.txt
7)使用写字板打开 d:BTR\a.txt
8) 最后代码停在: *q++ = *p++;.
9) 分析 bug原因.
10) 修改代码 *q++ = *p++; ==> *p++ = *q++;
11) build命令再次编译helloword
build d:\BTR\demo\win\helloworld
12)再次运行helloworld.exe
13) Helloworld.exe再次崩溃
14) 在bd命令提示符下
flash -s a.txt
15) 读取a.txt并分析bug原因.
16) 修改代码 :
char buf[ 5 ]; => char buf[ 20 ];
在printf("%s" , buf );之前插入 *q = 0;
17) build命令编译并运行helloworld.exe , 没有bug发现.
build d:\BTR\demo\win\helloworld
18) 退出比纯调试器( exit bd )
shutdown
1)demo目录: demo\win\hellowindow.
2)build命令编译 工程并运行demo\win\hellowindow\Debug\hellowindow.exe
3)当hellowindow.exe崩溃
flash -s a.txt
4)因为hellowindow.exe是多线程进程,使用筛选查看更清楚:
flash hellowindowview.cpp -s b.txt
或者:
fadd hellowindowview.cpp
...
flash -s b.txt
5)发现bug原因为野指针所致.
1)demo目录: demo\win\tstl and demo\win\tstl\usel. tstl工程创建库. usel工程调用库tstl.lib.
2)使用比纯调试器build命令编译 demo\win\tstl 工程
3)使用比纯调试器build命令编译 demo\win\tstl\usel
4)运行demo\win\tstl\usel\Debug\usel.exe. 进程无响应.
5)使用flash命令发现进程处于无限循环中.
flash -s a.txt
6)发现bug原因, 指针没有移动. 增加
p++;
1)demo目录: demo\win\tstdll and demo\win\tstdll\usedll. tstdll是dll工程. usedll工程调用tstdll.dll.
2)使用比纯调试器build命令编译demo\win\tstdll工程
3)使用比纯调试器build命令编译demo\win\usedll
4)运行demo\win\tstdll\usedll\Debug\usedll.exe. 进程崩溃.
5)使用flash命令发现dll已经载入 , 但是函数没有调用dll.
flash -s a.txt
6)发现bug原因为dll函数指针错了.修改:
DEFFUNC pFunc;
pFunc = ( DEFFUNC )( dll_load.GetDll函数( dll_handle ,"fntstdll") );
x = ( *pFunc )( atoi( str ) );
7)bdebug.ini增加:
[PV_FUNCTION]
( DllLoad , DllUnload )
a) bd
b)运行usedll.exe , usedll.exe结束
c) in bd ,使用F2热键暂停. 观察pv函数
pv
resource:10000000
[usedllDlg.cpp:00186] dll_handle = dll_load.DllLoad( "..\\..\\Debug\\tstdll.dll" );
1 unfree pointers.
d) dll_handle视为指针. dll_handle在整个 进程期间未释放. 因此增加代码行:
dll_load.DllUnload( dll_handle );
8) 我们建议usedll工程, tstdll工程两个工程同时由比纯调试器编译.比纯调试器能同时调试多个模块.
Windows下编译android工程
1) demo目录: demo\win\android
2) 检查SDK环境是否搭建, 检查NDK环境变量, 检查GRADLE_HOME环境变量
在PATH环境变量中检查android sdk\tools , android sdk\platform-tools , ndk-build gradle\gradlle-verno\bin
3) studio build , eclipse build or ant build your android project ok , here we use ant :
android.bat update project -n anprj -p ...\demo\win\android
ant debug
4) 手动编译成功,再交由比纯调试器编译。
build d:\BTR\demo\win\android
生成d:\BTR\demo\win\android\bin\anprj-debug.apk包
5) install
cd d:\BTR\demo\win\android\
adb install bin\anprj-debug.apk
6) windows下用比纯调试器调试
cd d:\BTR
./bd
bd >import /data/a.pkg
bd >lon
bd >fadd MainActivity.java
7) 在android手机界面中找到anprj应用程序, 双击运行之.
8) windows下用比纯调试器查看
bd > flash -s a.txt
bd > clog -s c.txt
bd >clog -m 5000 -s d.txt
查看a.txt c.txt d.txt, 就知android APP及jni实际运行情况了,代码若有错误一目了然。
Windows driver
1) demo目录: demo\win\driver readme: debug_driver_readme.txt
2) 编译 , 安装
bd
bd > build
d:\Windows_Driver_Kit_(WDK)_8.1_Samples\IOCTL\C++\sys
bd > build
d:\Windows_Driver_Kit_(WDK)_8.1_Samples\IOCTL\C++\exe
4) 调试
bd >
flash -s a.txt
...
see a.txt
1) demo目录: demo\win\qt readme: debug_qt_readme.txt
1. Install VS2012
2. Download qt-opensource-windows-x86-msvc2012-5.2.1.exe and install it.
3. Open Qt5.2.1 IDE
4. Use Qt5.2.1 IDE build example C:\Qt\Qt5.2.1\5.2.1\msvc2012\examples\gui\rasterwindow
5. Path=C:\Windows\system32;C:\Windows;...;C:\Qt\Qt5.2.1\5.2.1\msvc2012\bin
6. Run rasterwindow.exe out of Qt5.2.1 IDE , ( Note : if some dll not find , goto 5 to set Path
).
7. Install BTR debugger for win
for example : installed at d:\BTR
8. BTR build
bd
bd > build
C:\Qt\Qt5.2.1\5.2.1\msvc2012\examples\gui\rasterwindow
9. run rasterwindow.exe
10. BTR debugger see run log.
bd > flash -s a.txt
1) demo目录: demo/linux/helloworld
2) makefile, simplist makefile demo . Include make clean and make , 没有 bdebug.ini文件.
3) build命令编译
cd /home/usr/BTR
./bd
build /home/usr/BTR/linux/helloworld
4)运行
cd /home/usr/BTR/demo/linux/helloworld/release
./helloworld.exe
程序崩溃
5) flash命令查看崩溃行.
flash -s a.txt
/home/usr/BTR/a.txt
...
6) 错误行是:
[main.cpp : 00016 ] delete( pCMyHost );
7) 此简单错误请您尝试纠正.
1)demo目录: demo/linux/echo
2)makefile, like demo/linux/helloworld/makefile.
3)使用比纯调试器build命令编译 工程
cd /home/usr/BTR
./bd
build /home/usr/BTR/linux/echo
4)运行echo.exe
cd /home/usr/BTR/demo/linux/echo/release
./echo.exe
input send string(问: quit):
Q
5)使用pv命令查看内存泄漏
pv
There are one pointer unreleased:
[echosrv.cpp : 00083] m_pCTcp = new CTcp();
6) 请尝试纠正错误.
1) demo目录:
demo/linux/mylib
demo/linux/mydll
demo/linux/myexe
工程 myexe调用mylib静态库和mydll动态库.
2)使用build命令编译
./bd
build /home/usr/BTR/linux/mylib
build /home/usr/BTR/linux/mydll
build /home/usr/BTR/linux/myexe
3)运行/home/usr/BTR/linux/myexe/my.exe
./my.exe
进程崩溃 .
4)使用flash命令在bd终端
flash -s a.txt
打开a.txt查看知错误是
[mycp.cpp : 00019] while( *q ) *q++ = *p++;
5) bdebug.ini增加[PV_FUNCTION]
( DllLoad , DllUnload ) , 然后build命令编译 myexe 工程.
build /home/usr/BTR/linux/myexe
6)运行my.exe
./my.exe
input number:3
Library copy result=3
Call dll , segma( 3 ) = 6
7) 比纯调试器抛出一个错误.
错误20011: [pointer:0 ] wild pointer.
line is:
[main.cpp:00053] delete ( pCMyCP );
忽略错误报告,使用F3热键继续
进程退出.
8)使用pv查看资源管理bug.
pv
resource:09c990f0 [main.cpp:00042] handle = pCDllLoad->DllLoad( "../mydll/segma.因此" );
1 unfree pointers.
错误显示 DllUnload() 未调用.
9) 这儿建议myexe, mylib,mydll最好均由bd编译;如果bd只编译其中一个工程,其他工程手动编译,请记住makefile中添加 -lpthread -lrt编译参数。
1) demo目录: demo/linux/TheApp1
2) 使用linux KDE/c++ IDE 创建一工程名为theapp1
3) 增加按钮及标签, 增加事件代码. 尝试运行.
4) 退出KDE ,运行./设置 , make , make distclean.
cd demo/linux/TheApp1
./configure
make clean
make
5) 确信工程运行正常.
6) 比纯调试器build命令编译 KDE工程
./bd
build /home/usr/BTR/linux/TheApp1
7) 双击exe文件:
demo/linux/TheApp1/src/theapp1
8)使用比纯调试器命令跟踪进程.
flash -s a.txt
func -s b.txt
lon
...
clog -s c.txt
loff
9)由于TheApp1太大,抱歉我们删除了。您可以自己建KDE工程,让bd进行编译。
1) demo 位置:demo/linux/android
检查android-sdk , android-ndk , 检查ndk-build , 检查gradle\gradle-version\bin
2)cd demo/linux/android
android update project -n hello-jni -p .../demo/linux/android -t 1
ndk-build clean
3)手动编译hello-jni工程
cd demo/linux/android
ndk-build
ant debug --> 生成hello-jni-debug.apk
4)再用比纯调试器编译, 一次性编译NDK和SDK工程
cd /home/usr/BTR
./bd
bd >
bd >build /home/usr/BTR/demo/linux/android
bd >
5)安装hello-jni-debug.apk
adb install hello-jni-debug.apk
6) 运行hello-jni, 找到hello-jni图标 , 鼠标双击运行
7) linux 下检查用比纯调试器
bd >
bd >flash -s a.txt
bd >flash myfunc.c -s b.txt
bd >pid
bd >
8)阅读a.txt或b.txt, 如果hello-jni内含bug, 则a.txt中就可以发现.
1) demo 位置:demo/linux/driver
2)cd demo/linux/driver
make clean
make
再用比纯调试器编译, 生成myhello.ko
cd /home/usr/BTR
./bd
bd >
bd > build /home/usr/BTR/demo/linux/driver
bd >
3) install kernel module
su
insmod myhello.ko
4) 察看mod1.c
bd >
bd > flash
bd >
1) demo 位置:demo/linux/embed/test demo/linux/embed/embedlinux
配置交叉编译环境
2)cd demo/linux/embed/test
make clean
make
3)再用比纯调试器编译, 编译时指定生成比纯调试器的局域网IP, 最后生成embedtest.exe
cd /home/usr/BTR
./bd
bd >
bd > build /home/usr/BTR/demo/linux/embed/test
bd >
4) download embedtest.exe to your embed device , run embedtest.exe
tftp > get embedtest.exe
#chmod 0755 embedtest.exe
./embedtest.exe
5) 比纯调试器调试命令
bd >
bd > flash -s a.txt
6) demo/linux/embed/embedlinux 是另一个练习
1) demo目录: demo\linux\qt\first
2) build命令编译
bd > build /home/user/BTR/demo/linux/qt/first
bd >
3) run first
$> cd /home/user/BTR/demo/linux/qt/first
./first
4) flash
bd >
bd > flash
1) demo目录: demo\win\javahello
使用eclipse(或其它工具)生成一工程. eclipse将*.java与*.class放入不同路径. 此处*.java与*.class处理相同路径.
2) build命令编译 demo\win\javahello
bd >
build d:\BTR\demo\win\javahello
5)运行java
cd d:\BTRdemo\win\javahello_BTR\top
java -jar f1.jar
6) 查看运行日志.
flash -s a.txt
7) 在代码中增加比纯调试器输出调试消息 API . 函数 bprint() 定义在jni\bdg.java中.
bdg.bprint( "test x+y" );
bdg.bprint( s );
如以后不使用比纯调试器, 请删除bdg.bprint()代码行, 否则将导致错误.
8) build命令再次编译demo\win\javahello ,再次运行java
9) 观察bdg.bprint()发送至比纯调试器的消息串.
确信您已经安装J2EE.
1) demo目录: demo\win\servlet
2) 创建make.bat
3) 设置bdebug.ini
*.java 映射 其 *.class 路径必须在bdebug.ini中指定
[JAVA_PKGMAP]
...\demo\win\servlet\src :
...\demo\win\servlet\test\WEB-INF\classes
4) build命令编译
bd >
build命令编译 demo\win\servlet
5) run demo\win\servlet_BTR\brun.bat 进行部署
启动tomcat , 布署servlet.
您可启动tomcat , websphere或者weblogical,或者其他第三方产品. 如果TestServlet.war布署成功 , 然后您可使用比纯调试器调试了.
6)使用IE浏览器 , 输入 url:
http://127.0.0.1:8080/TestServlet
7)在比纯调试器窗口使用flash命令, 查阅servlet代码运行现场.
flash
该例子依赖于您的javaweb是何种安装. 例子中C:\apache-tomcat-7.0.23\webapps\examples\WEB-INF\classes\jsp2\examples是一个javabean.
1)使用比纯调试器build编译命令
bd >
build C:\apache-tomcat-7.0.23\webapps\examples\WEB-INF\classes\jsp2\examples
2) 修改并运行 demo\win\JavaBean_BTR\brun.bat进行部署
启动tomcat
3)在IE里, 输入URL:
http://127.0.0.1:8080/examples/jsp/jsp2/simpletag/book.jsp
4)使用比纯调试器查看正在运行的java bean.
flash -s a.txt
5)打开a.txt查看代码运行现场.
1)demo目录: demo\win\cs.
2)build命令编译demo
bd >
build ...\demo\win\cs
3)运行c# 工程.
双击demo\win\cs\obj\Debug\cs.exe.一C#窗体显示.
4)使用比纯调试器,查看代码运行现场:
flash -s a.txt
BSD UNIX下的调试示例与linux下相同,比纯调试器调试它们的方法也完全一致,只有makefile稍有不同,详情参阅unix下示例代码。
比纯调试器在BSD UNIX下暂不支持java调试。
源码序列:
1) if ( b )
问: 为什么 "[00016][x.cpp]if ( b ) goto LABEL_EXIT;" 出现两次?
答: [00016][x.cpp]if ( b ) goto LABEL_EXIT;
[00016][x.cpp]if ( b ) goto LABEL_EXIT;
正确 , 因为b == true.
2) 线程崩溃
问:以下代码日志:
[00016][x.cpp] x = 1;
[00260][x.cpp] x += strlen(
s );
[05012][y.cpp] while( bOk
) {
[05013][y.cpp] Sleep( 300 );
[05013][y.cpp] Sleep( 300 );
...
[05013][y.cpp] Sleep( 300 );
哪一行代码崩溃?
答: "[00260][x.cpp] x += strlen( s ); "崩溃 . 因为x.cpp运行在线程A. y.cpp运行在线程B. [00260][x.cpp]语句本身不会退出函数体之外,但是却没有接下来的语句. 因此strlen( s )是崩溃行.
3)崩溃在 int x = 0;
问:以下代码日志:
[00906][x.cpp] pCSegma->segma( num ) ;
[01509][segma.cpp] int x = 0;
进程崩溃在代码行[01509][segma.cpp] , 为什么 ?
答: 因为pCSegma是野指针. 有时pCSegma的地址不会引起崩溃, 但因为没有内存分配给pCSegma. 您应该检查代码中是否有 "pCSegma = new ..."这样的语句出现.
Value Trace
1) value log
[00055][x.cpp] bwatch(
"NUM" , &num , 4 );
NUM: 00 00 00 00 [int]=0 [uint]=0
[01026][y.cpp] num++;
NUM: 01 00 00 00 [int]=1 [uint]=1
[01026][y.cpp] num++;
NUM: 02 00 00 00 [int]=2 [uint]=2
[03016][x.cpp] num--;
NUM: 01 00 00 00 [int]=1 [uint]=1
[03062][z.cpp] pPersonItem->sex
= MAN;
NUM: 5B 00 00 00 [int]=91 [uint]=91
[03016][x.cpp] num--;
NUM: 5A 00 00 00 [int]=90 [uint]=90
问: 代码行[03062][z.cpp] 改变了变量num的值 , 为什么?
答: 因为pPersonItem是野指针 . 变量 sex地址与变量num地址相同 , 因此值num改变.
VC demo
1) build命令编译失败
问: 我复制demo工程到我的硬盘 , 我不能用build命令编译一些 VC 工程, 为什么?
答: 请首先在visual studio集成环境中编译成功 . 因为visual studio环境改变了, 输出路径改变了.然后再用比纯调试器编译。定能成功。
KDE demo
1) build命令编译失败
问: 我复制 demo工程到我的 硬盘 , 我 不能用build命令编译, 为什么?
答: 请再次在 您的linux中创建KDE工程 . 然后使用命令./configure, make clean, make , make distclean 逐个手动检查 是否成功. 然后再尝试用比纯调试器编译.
顺便告之 , 您可尝试其它x-window界面IDE工具. 生成Makefile并尝试使用比纯调试器build命令编译这些工程.
2) build命令编译失败
问:我不能build命令编译 KDE窗体demo例子 , 为什么?
答:请检查是否您的linux已经安装KDE. 无KDE的库支持也不能成功.
BTRweb
1)字符乱码
问:我使用BTRweb , 有时我发现字符乱码 , 为什么?
答:请设置为UTF字符集.
2)c#
问:我使用BTRweb浏览test.cs代码文件, 我发现字符乱码.
答:因为在 *.cs文件中开始3字节(0xEF 0xBB 0xBF)是微软c#文件标识. 因此字符乱码. IE或者firefox不能识别这些字符.
因此您可浏览c#文件 , 但是不能使用BTRweb.exe修改他们.
Android
1)无调试信息
问:我的android工程第一次运行有调试信息,用flash可以列出来, 再次运行工程,用flash就只有0行了,怎么办?
答:可能是android app一直在运行,您可以先彻底关闭android device, 再打开android device. 再运行bd,用flash就可看到调试信息了.