I have following c++ code
int myvar=1;
void test1( int j)
{
int b=j+1;
}
void main()
{
myvar=2;
test1(50);
myvar=3;
test1(100);
myvar=6;
test1(200);
}
I'm trying to set a breakpoint that stops if myvar is greater than 4 when running function test1.
Here is my breakpoint:
bp test!test1 ".if ( poi(myvar)>0n4) {} .else {gc} "
however, it stops every time test1 is executed...
The executable file is called test.exe, a 64 bit application.
Any suggestion would be appreciated.
A little bit of debugging in the breakpoint reveals what is happening:
0 e Disable Clear 00007ff6`77e11410 [f:\projects\windbg_help\main.cpp # 4] 0001 (0001) 0:**** windbg_help!test1 "?? myvar; r $t1=myvar; ?? #$t1; r $t2=poi(myvar); ?? #$t2; .if (dwo(myvar) > 0n4) {.echo yes; gc} .else {.echo no; gc} "
I set the t1 temp register to myvar, and t2 temp register to the contents of myvar, then display them:
0:000> g
int 0n2
unsigned int64 0x00007ff6`77e1c000
unsigned int64 0xffffffff`00000002
no
int 0n3
unsigned int64 0x00007ff6`77e1c000
unsigned int64 0xffffffff`00000003
no
int 0n6
unsigned int64 0x00007ff6`77e1c000
unsigned int64 0xffffffff`00000006
yes
ModLoad: 00007ff9`c8520000 00007ff9`c8531000 C:\WINDOWS\System32\kernel.appcore.dll
ModLoad: 00007ff9`c9da0000 00007ff9`c9e3e000 C:\WINDOWS\System32\msvcrt.dll
ModLoad: 00007ff9`c9aa0000 00007ff9`c9bc2000 C:\WINDOWS\System32\RPCRT4.dll
ntdll!NtTerminateProcess+0x14:
00007ff9`cc5cfcd4 c3 ret
Notice how poi(myvar) is returning a 64bit value, and the upper 32bits are set. You poi(myvar) > 0n4 comparison is saying:
if (0xffffffff0000000? > 4) then { always true }
use dwo(myvar) instead to read only the 32bit contents
Related
class Test
{
public:
Test()
{
std::cout << "ctor" << std::endl;
ptr = new int(5);
*(ptr + 1) = 42;
};
~Test() { std::cout << "dtor" << std::endl; };
int* ptr;
};
void foo()
{
Test test;
}
int main()
{
foo();
return 0;
}
In the above example I want to set a data breakpoint at the address pointed to by ptr plus an offset (4 bytes in this case), to detect the heap corruption.
After I break inside the Test constructor, I have tried using the following to set the breakpoint but have failed:
0:000> ba w 4 (ptr + 4)
Bp expression '(ptr + 4)' could not be resolved, adding deferred bp
*** Bp expression '(ptr + 4)' contains symbols not qualified with module name
If I put the address manually then it obviously works. But I don't want to hard code the address in the command because I am doing this as part of a script and the address inside ptr can change every time.
What is the correct syntax for adding the data breakpoint without hardcoding the address?
You need ##c++() or .expr /s c++:
0:000> bp MemoryBreak!Test::Test
0:000> g
Breakpoint 2 hit
MemoryBreak!Test::Test:
[...]
0:000> l+t
Source options are 1:
1/t - Step/trace by source line
0:000> p
MemoryBreak!Test::Test+0x42:
0:000> ? ##c++(ptr)
Evaluate expression: 2790386541360 = 00000289`afffa330
0:000> ba w 4 ##c++(ptr)+4
0:000> bl
1 e Disable Clear 00007ff7`5fac2720 [C:\....cpp # 23] 0001 (0001) 0:**** MemoryBreak!main
2 e Disable Clear 00007ff7`5fac1fa0 [C:\....cpp # 6] 0001 (0001) 0:**** MemoryBreak!Test::Test
3 e Disable Clear 00000289`afffa334 w 4 0001 (0001) 0:****
0:000> g
Breakpoint 3 hit
MemoryBreak!Test::Test+0xa7:
In Windbg I have a script that iterates through the frames of a stack and does a good job of pulling back things of interest, echoing them to the Command Window (it just sniffs things out that could require further investigation).
In certain frames, there will be a this that I'm interested in some details of. I can certainly extract the details fine, but I'd like to get the actual class type from it too. I know that if I then do a dv /t I will see something like the following:
0:115> .frame 14
0:115> dv /t
class foo1 * this = 0x00000000e9ed0010
I would like a way of being able to pass just foo1 to a .printf command.
In frames that have more than simply this, I can restrict output by using the pattern dv /t this obviously, but is there a good way of having something like what follows in a frame and me being able to extract just foo1?
0:115> .frame 17
0:115> dv /t
class foo1 * this = 0x00000000f3e2f568
class foo2 * bar2 = 0x0000000000000001
bool _somebool = true
Doing what follows is very close to the limited output I'd like... but I just want to neaten it up.
0:115> .frame 17
0:115> dv /t this
class foo1 * this = 0x00000000f3e2f568
Following the example code from blabb:
0:000> dv /t
class Time * this = 0x001efb24
int h = 0n23
int m = 0n59
int s = 0n59
0:000> dv /t this
class Time * this = 0x001efb24
0:000> some command
Time
The third command is what I'm looking for.
What I understood is: you need a command that takes foo1 as a parameter and gives an output like dv /t but just for all foo1.
IMHO, it's hardly possible with builtin WinDbg functionality. You could fiddle around with .foreach inculding $spat and the like.
One possibility is .shell along with the command line tool findstr or Cygwin grep. But that's not convenient, because it always outputs Process started etc. You could again work around this using .foreach and skipping some tokens, but that's tedious.
There are grep implementations for WinDbg such as long123king's grep plugin and if I recall correctly, there's also a grep implementation in PDE.
Then there is pykd, which has the powers of Python and let's you do basically anything.
i am not sure i understand what you need
but have you given the new dx expression evaluator a try
for example
0:000> dv /t
class Time * this = 0x001efb24
int h = 0n23
int m = 0n59
int s = 0n59
0:000> dv /t this
class Time * this = 0x001efb24
0:000> dx #$curstack.Frames[0].LocalVariables
#$curstack.Frames[0].LocalVariables
this : 0x1efb24 [Type: Time *]
0:000> dx #$curstack.Frames[0].LocalVariables.this
#$curstack.Frames[0].LocalVariables.this : 0x1efb24 [Type: Time *]
[+0x000] hour : 23 [Type: int]
[+0x004] minute : 59 [Type: int]
[+0x008] second : 59 [Type: int]
you can enhance this with javascript to fine tune it to you needs
here is how you can enhance this with javascript
make a file whateverfoo.js with contents below
function log(logstr) {
return host.diagnostics.debugLog(logstr + "\n")
}
function locvartgttyp(frameno)
{
log( host.currentThread.Stack.Frames[frameno].LocalVariables.this.targetType.name)
}
and use it like
:\>echo %wdbg%
"c:\Program Files\Windows Kits\10\Debuggers\x86\cdb.exe"
:\>%wdbg% time.exe
Microsoft (R) Windows Debugger Version 10.0.17763.132 X86
0:000> g time!main
time!main:
01237a80 55 push ebp
0:000> tc;t
time!Time::Time:
01231140 55 push ebp
0:000> dv /t
class Time * this = 0x00000002
int h = 0n23
int m = 0n59
int s = 0n59
0:000> .load jsprovider
0:000> .scriptload c:\wdscr\locvar.js
JavaScript script successfully loaded from 'c:\wdscr\locvar.js'
0:000> dx #$scriptContents.locvartgttyp(0)
Time *
#$scriptContents.locvartgttyp(0)
0:000>
Trying to set breakpoint to class member, but I get syntax error or error saying "could not resolve".
Target variable is abc of class pointer xyz.
0:000> ??##c++(xyz->abc)
short 0n812
0:000> dt xyz
Local var # rbx Type Prop*
+0x000 __VFN_table : 0x00007ffd`b9229510
+0x058 abc : 0n0147
Attempts:
0:000> bu ***!***::function+0x56 ".if (##c++(xyz->abc))==147) {.echo 'hit'} .else {gc}"
^ Syntax error in '.if ....'
I want to set breakpoint when pProp->ydu value is equal to 147.
source
#include <iostream>
using namespace std;
class Rectangle {
int width, height;
public:
Rectangle (int x ,int y) : width(x) , height(y) {}
int area (void) {return (width*height);}
};
void CalcArea(int i,int j,Rectangle *rect) {
cout << "Area for Rect("<<i<<","<<j<<") = "<<rect->area()<< endl;
}
int main () {
int i,j;
for(i=10,j=10; (i<100 && j<100); i+=5,j+=10){
Rectangle rect (i,j);
CalcArea(i,j,&rect);
}
return 0;
}
compiled with vs 2017 community cmd prompt
cl /EHsc /W4 /analyze /Zi /Od classy.cpp /link /release
executed
classy.exe
Area for Rect(10,10) = 100
Area for Rect(15,20) = 300
Area for Rect(20,30) = 600
Area for Rect(25,40) = 1000
Area for Rect(30,50) = 1500
Area for Rect(35,60) = 2100
Area for Rect(40,70) = 2800
Area for Rect(45,80) = 3600
Area for Rect(50,90) = 4500
loaded in windbg and set a conditional break point and run
:\>cdb classy.exe
Microsoft (R) Windows Debugger Version 10.0.16299.15 X86
0:000> bu classy!CalcArea ".if(((##c++(rect->width))==0n40)){ .echo \"hit\" } .else{gc}"
0:000> bl
0 e 00841100 0001 (0001) 0:****
classy!CalcArea ".if( ((##c++(rect->width))==0n40) ) { .echo \"hit\" } .else {gc}"
0:000> g
Area for Rect(10,10) = 100
Area for Rect(15,20) = 300
Area for Rect(20,30) = 600
Area for Rect(25,40) = 1000
Area for Rect(30,50) = 1500
Area for Rect(35,60) = 2100
hit <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
eax=00000028 ebx=7ffdf000 ecx=002dff08 edx=00000046 esi=008c9bf0 edi=000d8b28
eip=00841100 esp=002dfef8 ebp=002dff18 iopl=0 nv up ei ng nz na pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000287
classy!CalcArea:
00841100 55 push ebp
0:000> ?? rect
class Rectangle * 0x002dff08
+0x000 width : 0n40 <<<<<<<<<<<<<<<
+0x004 height : 0n70
0:000>
Im struggling with fatfs on stm32f4. With no problem i can mount, create file and write on it by : char my_data[]="hello world" and in windows file shows normally but when i try use code as loger :
float bmp180Pressure=1000.1;
char presur_1[6];//bufor znakow do konwersji
sprintf(presur_1,"%0.1f",bmp180Pressure);
char new_line[]="\n\r";
if(f_mount(&myFat, SDPath, 1)== FR_OK)
{
f_open(&myFile, "dane.txt", FA_READ|FA_WRITE);
f_lseek(&myFile, f_size(&myFile));//sets end of data
f_write(&myFile, presur_1, 6, &byteCount);
f_write(&myFile, new_line,4, &byteCount);
f_close(&myFile);
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
}
When i was read from computer i have :top : notepad ++ buttom :windows notepad
There are at least two problems in your code:
The string for the number is too short. C strings are terminated with a null byte. So presur_1 needs to be at least 7 bytes long (6 for the number and 1 for the null byte). Since it's only 6 bytes long, sprintf will write beyond the allocated length and destroy some other data.
The string for the newline is initialized with a string of 2 characters (plus the null byte). However, you write 4 characters to the file. So in addition to the newline, a NUL character and a garbage byte will end up in the file.
The fixed code looks like this:
float bmp180Pressure = 1000.1;
char presur_1[20];//bufor znakow do konwersji
int presur_1_len = sprintf(presur_1,"%0.1f\n\r",bmp180Pressure);
if(f_mount(&myFat, SDPath, 1)== FR_OK)
{
f_open(&myFile, "dane.txt", FA_READ|FA_WRITE);
f_lseek(&myFile, f_size(&myFile));//sets end of data
f_write(&myFile, presur_1, presur_1_len, &byteCount);
f_close(&myFile);
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);
}
My tests are in SystemC env and for all my tests i run a common routine(basically its my init sequence which doesn't vary much based on seed). This common routine is followed by my actual test.
It looks something like this:
Test_MAIN
init_seq();
my_test();;
Here init_seq() is that common routine and my_test() is my actual test that have actual test sequence which initiate multiple SC threads, for initiating various kind of traffic.
Now, my problem is that i want a way to avoid init_seq() for every run. The entire test should run for one time and the next time i should have a mechanism to directly run from my_test()(which is basically skipping/preloading init_seq() part to the simulator).
VCS save and restore can't be used directly as in this case we also will have to restore the SystemC variables.
Could you please direct me on this..!!
Thanks
ByreddyNaresh
I tried with a SystemC test with init() and run() routine, and use VCS save/restart to restore the test. It seems OK to me that a member variable 'cnt' in test is restored successfully.
This is my test:
// test.h
#ifndef TEST_H
#define TEST_H
#include <systemc.h>
class test: public sc_module{
public:
sc_in<bool> init_start;
sc_in<bool> run_start;
void init();
void run();
int cnt;
SC_CTOR(test){
SC_THREAD(init);
sensitive_pos << init_start;
dont_initialize();
SC_THREAD(run);
sensitive_pos << run_start;
dont_initialize();
}
};
#endif
and
// test.cpp
#include "test.h"
void test::init(){
printf("test init:\n");
while(1){
cnt = 10;
printf("init cnt to %d\n", cnt);
wait();
}
}
void test::run(){
printf("test run:\n");
while(1){
cnt++;
printf("cnt = %d\n", cnt);
wait();
}
}
and the top:
// tb.v
module tb;
reg init_start;
reg run_start;
initial begin
init_start = 0;
run_start = 0;
#100
init_start = 1;
#100
$save("save.chk");
#100
run_start = 1;
#100
$finish;
end
test u_test(
.init_start(init_start),
.run_start(run_start)
);
endmodule
After 'save.chk' is generated, I run it directly and the output is:
$ save.chk
Chronologic VCS simulator copyright 1991-2012
Contains Synopsys proprietary information.
Compiler version G-2012.09; Runtime version G-2012.09; Mar 5 18:01 2014
test run:
cnt = 11
$finish called from file "tb.v", line 17.
$finish at simulation time 1300
V C S S i m u l a t i o n R e p o r t
Time: 1300 ps
CPU Time: 0.260 seconds; Data structure size: 0.0Mb
Wed Mar 5 18:01:08 2014
It seems variable 'cnt' is restored from '10', as is done in init() routine.
Don't know if this is the case you met?