Flexcan doesn't apply all filters - filter

I use MK24F12. I adjusted Flexcan module to gather messages from device using Fleet Management Systems Interface.
I turned RxFIFO on and set ID acceptance mode as Format A. Then i filled filter table (it starts at 7th mailbox) with IDs and according RXIMR registers with Mask. The rest filters i filled with 0x40000000 and the rest mask registers with 0x5FFFFFFF.
When i start to listen to device i get some frames, but here's the problem i don't get all messages device sent, despite they match filters.
i know that because if i set any mask register as zero i get all of messages on bus.
i noticed that hit filter (RXFIR register) is (0,1,4,5,...), so in other words i get messages which match filters that stored in registers CSn and IDn of MailBox.
Below is log, here i added 7 filters and i got just 4 types of messages. Then i removed all filters and as you can see i skipped a lot of messages that supposed being caught.
[1.003] Filter added (Type: Ext, ID: 0x00FEE900, Mask: 0x00FFFF00)
[1.004] Filter added (Type: Ext, ID: 0x00FEFC00, Mask: 0x00FFFF00)
[1.005] Filter added (Type: Ext, ID: 0x00FEEE00, Mask: 0x00FFFF00)
[1.006] Filter added (Type: Ext, ID: 0x00FEC100, Mask: 0x00FFFF00)
[1.007] Filter added (Type: Ext, ID: 0x00F00400, Mask: 0x00FFFF00)
[1.008] Filter added (Type: Ext, ID: 0x00FEE500, Mask: 0x00FFFF00)
[1.008] Filter added (Type: Ext, ID: 0x00FEEA00, Mask: 0x00FFFF00)
[1.935] CAN.Got frame (Type: Ext, ID: 0x18F00420, Data: FF FF FF 80 0C FF FF FF, Filter: 4)
[2.436] CAN.Got frame (Type: Ext, ID: 0x18FEE520, Data: 58 1C 00 00 FF FF FF FF, Filter: 5)
[2.938] CAN.Got frame (Type: Ext, ID: 0x18FEE920, Data: FF FF FF FF 59 1C 00 00, Filter: 0)
[3.439] CAN.Got frame (Type: Ext, ID: 0x18FEFC20, Data: FF 48 FF FF FF FF FF FF, Filter: 1)
[4.944] CAN.Got frame (Type: Ext, ID: 0x18F00420, Data: FF FF FF C0 12 FF FF FF, Filter: 4)
[5.445] CAN.Got frame (Type: Ext, ID: 0x18FEE520, Data: 59 1C 00 00 FF FF FF FF, Filter: 5)
[6.950] CAN.Got frame (Type: Ext, ID: 0x18FEE920, Data: FF FF FF FF 5A 1C 00 00, Filter: 0)
[7.452] CAN.Got frame (Type: Ext, ID: 0x18FEFC20, Data: FF 46 FF FF FF FF FF FF, Filter: 1)
[8.957] CAN.Got frame (Type: Ext, ID: 0x18F00420, Data: FF FF FF 00 19 FF FF FF, Filter: 4)
[9.458] CAN.Got frame (Type: Ext, ID: 0x18FEE520, Data: 5A 1C 00 00 FF FF FF FF, Filter: 5)
at this point i removed all filters
[34.186] CAN.Got frame (Type: Ext, ID: 0x18F00420, Data: FF FF FF 00 4B FF FF FF, Filter: 0)
[34.688] CAN.Got frame (Type: Ext, ID: 0x18FEE520, Data: 62 1C 00 00 FF FF FF FF, Filter: 0)
[35.190] CAN.Got frame (Type: Ext, ID: 0x18FEE920, Data: FF FF FF FF 63 1C 00 00, Filter: 0)
[35.691] CAN.Got frame (Type: Ext, ID: 0x18FEFC20, Data: FF 34 FF FF FF FF FF FF, Filter: 0)
[36.193] CAN.Got frame (Type: Ext, ID: 0x18FEEE20, Data: 56 FF FF FF FF FF FF FF, Filter: 0)
[36.694] CAN.Got frame (Type: Ext, ID: 0x18FEC120, Data: AD 05 00 00 FF FF FF FF, Filter: 0)
[37.196] CAN.Got frame (Type: Ext, ID: 0x18F00420, Data: FF FF FF 40 51 FF FF FF, Filter: 0)
[37.698] CAN.Got frame (Type: Ext, ID: 0x18FEE520, Data: 63 1C 00 00 FF FF FF FF, Filter: 0)
[39.203] CAN.Got frame (Type: Ext, ID: 0x18FEE920, Data: FF FF FF FF 64 1C 00 00, Filter: 0)
[39.704] CAN.Got frame (Type: Ext, ID: 0x18FEFC20, Data: FF 32 FF FF FF FF FF FF, Filter: 0)
[40.206] CAN.Got frame (Type: Ext, ID: 0x18FEEE20, Data: 58 FF FF FF FF FF FF FF, Filter: 0)
[40.707] CAN.Got frame (Type: Ext, ID: 0x18FEC120, Data: AD 05 00 00 FF FF FF FF, Filter: 0)
Here's picture of FlexCAN registers' values

I have found that I read CODE bits of MB's CS register and it was 1 for filters 2,3,6,7... that means BUSY. But if MB is used by FIFO engine it doesn't contain CODE bits and we shouldn't check Message Buffer Code at all.
They might if don't use some bits keep them clear.
Question is closed.
Here's picture of MB and FIFO structure

Related

Memory troubles in a DIY gcc csv reader

Writing some code to reformat some CSV data.
It's been a while since I was working in C and doing programming with memory management this raw, and I don't have a lot of experience with many of the tools for debugging memory allocation.
Diving right in I found some forum posts suggesting compiling like this to figure out where the segmentation fault was originating.
gcc -o CSVreader_v0.0-memcheck -static-libasan -O -g -fsanitize=address -fno-omit-frame-pointer -Wall -Wno-unused-result CSVreader.c
My only problem is I have no idea how to interpret the output can someone help walk me through this or point me to a guide on what all this means.
==9474==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000015 at pc 0x7f1a330533a6 bp 0x7ffedc0840d0 sp 0x7ffedc083878
WRITE of size 6 at 0x602000000015 thread T0
#0 0x7f1a330533a5 (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x663a5)
#1 0x55a46460155a in parseRow (/home/kodachi/workspace/Tactical Engram/CSVreader_v0.0+0x155a)
#2 0x55a4646018e5 in parseCSV (/home/kodachi/workspace/Tactical Engram/CSVreader_v0.0+0x18e5)
#3 0x55a464601c7b in main (/home/kodachi/workspace/Tactical Engram/CSVreader_v0.0+0x1c7b)
#4 0x7f1a32e220b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#5 0x55a46460122d in _start (/home/kodachi/workspace/Tactical Engram/CSVreader_v0.0+0x122d)
0x602000000015 is located 0 bytes to the right of 5-byte region [0x602000000010,0x602000000015)
allocated by thread T0 here:
#0 0x7f1a330cbb40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
#1 0x55a4646014f1 in parseRow (/home/kodachi/workspace/Tactical Engram/CSVreader_v0.0+0x14f1)
#2 0x55a4646018e5 in parseCSV (/home/kodachi/workspace/Tactical Engram/CSVreader_v0.0+0x18e5)
#3 0x55a464601c7b in main (/home/kodachi/workspace/Tactical Engram/CSVreader_v0.0+0x1c7b)
#4 0x7f1a32e220b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x663a5)
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa[05]fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==9474==ABORTING
I'd like to understand what all this means but equally if someone can point me to how I can get a more human readable output that would also be helpful, I tried valgrind, but I'm not sure I was using it correctly.
Right now my code is taking the first line of the csv file using
fscanf(fp, "%[^\n]\n", line_buffer);
with char* line_buffer and char** hStrings to store the column headers, I pass &linebuffer and &hStrings into the following function to parse the column headers in the 'line_buffer' string into 'hStrings' with the delimiting character being '|'.
/**
* Split str around the '|' character and store the data in dStr
**/
int parseRow(char** str, char*** dStr)
{
unsigned int columns = 0;
char* col;
printf("Splitting: %s\n", *str);
col = strsep(str, "|");
while(col != NULL && hasPrint(col, 0, strlen(col)))
{
printf("\n");
(*dStr)[columns] = malloc(strlen(col)*sizeof(char));
strcpy((*dStr)[columns], col);
columns++;
col = strsep(str, "|");
}
//printf("\n");
printf("counted: %d columns\n", columns);
return columns;
}
Before I was using `-fsanitize=address' the program would run this part correctly and a segmentation fault would occur later when I was parsing the rows of data, not the column headers. Now it generates the output I provided as it is working on the first row containing the headers. Not sure if that helps understand what's going on here.

How to generate a deterministic set of UUIDs in golang

I'm doing some testing and it would be useful to have a known set of UUIDs that are getting used by our code. However, I'm having trouble figuring out how to create a deterministic set of UUIDs in golang.
I've tried a few approaches, but neither seemed to work:
type KnownReader struct {
store *Store
}
type Store struct {
val uint16
}
func (r KnownReader) Read(p []byte) (n int, err error) {
ret := r.store.val
r.store.val = ret + 1
fmt.Printf("\nStore: %v", r.store.val)
p = make([]byte, 4)
binary.LittleEndian.PutUint16(p, uint16(ret))
fmt.Printf("\nreader p: % x", p)
return binary.MaxVarintLen16, nil
}
func main() {
r := KnownReader{
store: &Store{val: 111},
}
uuid.SetRand(r)
u, _ := uuid.NewRandomFromReader(r)
fmt.Printf("\n%v",u)
u, _ = uuid.NewRandomFromReader(r)
fmt.Printf("\n%v",u)
}
---- OUTPUT ----
Store: 1
reader p: 00 00 00 00
Store: 2
reader p: 01 00 00 00
Store: 3
reader p: 02 00 00 00
Store: 4
reader p: 03 00 00 00
Store: 5
reader p: 04 00 00 00
Store: 6
reader p: 05 00 00 00
00000000-0000-4000-8000-000000000000
Store: 7
reader p: 06 00 00 00
Store: 8
reader p: 07 00 00 00
Store: 9
reader p: 08 00 00 00
Store: 10
reader p: 09 00 00 00
Store: 11
reader p: 0a 00 00 00
Store: 12
reader p: 0b 00 00 00
00000000-0000-4000-8000-000000000000
As you can see, the UUID, does not change between calls
I also tried using uuid.FromBytes, but that didn't seem to work either:
func getbytes(num uint16) []byte {
p := make([]byte, 4)
binary.LittleEndian.PutUint16(p, num)
fmt.Printf("\ngetbytes p: % x", p)
return p
}
func main() {
var i uint16 = 0
fmt.Printf("\nout getbytes: % x", getbytes(i))
u, _ := uuid.FromBytes(getbytes(i))
i = i + 1
fmt.Printf("\nUUID: %v", u)
fmt.Printf("\nout getbytes: % x", getbytes(i))
u, _ = uuid.FromBytes(getbytes(i))
fmt.Printf("\nUUID: %v", u)
}
---- OUTPUT ----
getbytes p: 00 00 00 00
out getbytes: 00 00 00 00
getbytes p: 00 00 00 00
UUID: 00000000-0000-0000-0000-000000000000
getbytes p: 01 00 00 00
out getbytes: 01 00 00 00
getbytes p: 01 00 00 00
UUID: 00000000-0000-0000-0000-000000000000
As you can see the UUIDs are still the same here as well.
So, is there something I'm missing? How can I get a consistent set of UUIDs?
Thanks
Thanks Adrian, I think I figured out the answer:
rnd := rand.New(rand.NewSource(1))
uuid.SetRand(rnd)
u, _ = uuid.NewRandomFromReader(rnd)
fmt.Printf("\n%v", u)
u, _ = uuid.NewRandomFromReader(rnd)
fmt.Printf("\n%v", u)
--- OUTPUT ---
52fdfc07-2182-454f-963f-5f0f9a621d72
9566c74d-1003-4c4d-bbbb-0407d1e2c649

parse the following ibeacon packet

I am trying to parse this ibeacon packet received by scanning through a hci socket
b'\x01\x03\x00\x18\xbe\x99m\xf3\x14\x1e\x02\x01\x1a\x1a\xffL\x00\x02\x15e\xec\xe2\x90\xc7\xdbM\xd0\xb8\x1aV\xa6-b 2\x00\x00\x00\x02\xc5\xcc'
hex format 01 03 00 18 be 99 6d f3 14 1e 02 01 1a 1a ff 4c 00 02 15 65 ec e2 90 c7 db 4d d0 b8 1a 56 a6 2d 62 20 32 00 00 00 02 c5 cc
the parameters after applying the parser are
'UUID': '65ece290c7db4dd0b81a56a62d622032', 'MAJOR': '0000', 'MINOR': '0002', 'TX': -59, 'RSSI': -60
I am not sure if the RSSI portion of this parsing is right.
Referring to this https://stackoverflow.com/a/19040616/10355673
the last bit of the beacon advertising packet is the TX power value.
so how do we get the rssi value? here, I have taken rssi to be cc and tx to be c5. Is this correct?
There are flags headers before the manufacturer advertisement sequence shown below, but you really don't care about the flags. Here are the bytes you care about:
ff # manufacturee adv type
4c 00 # apple Bluetooth company code
02 15 # iBeacon type code
65 ec e2 90 c7 db 4d d0 b8 1a 56 a6 2d 62 20 32 # proximity uuid
00 00 # major
00 02 # minor
c5 # measured power (tx power)
cc # crc
Proximity UUUD: 65ece290-c7db-4dd0-b81a-56a62d622032,
Major: 0,
Minor: 2,
Measured Power: -59 dBm
The RSSI is not part of the transmitted packet, but a measurement taken by the receiver based on the strength of the signal. It will typically be a slightly different value for each packet that is received. You get this value from an API on a mobile device or embedded system that fetches it from the bluetooth chip.

Armadillo and OpenMP and stack-use-after-scope

I have an issue with a stack-use-after-scope with error with the C++ Armadillo library within an OpenMP blog in an R package and I cannot figure out what is wrong. The complete gcc log is here from the CRAN GCC ASAN check of the R-package. I have have kept the relevant part of the log below
==33791==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffd03364940 at pc 0x7ff8127abc07 bp 0x7ffd03364680 sp 0x7ffd03364670
WRITE of size 4 at 0x7ffd03364940 thread T0
#0 0x7ff8127abc06 in arma::Mat<double>::Mat(double*, unsigned int, unsigned int, bool, bool) /data/gannet/ripley/R/test-3.5/RcppArmadillo/include/armadillo_bits/Mat_meat.hpp:1215
#1 0x7ff8129fb0c2 in GMA<logistic>::solve() [clone ._omp_fn.0] /data/gannet/ripley/R/test-3.5/RcppArmadillo/include/armadillo_bits/Col_meat.hpp:411
#2 0x7ff825ae2cde in GOMP_parallel (/lib64/libgomp.so.1+0xdcde)
#3 0x7ff812a0c9f8 in GMA<logistic>::solve() ddhazard/GMA_solver.cpp:83
#4 0x7ff81276421d in ddhazard_fit_cpp(...
Address 0x7ffd03364940 is located in stack of thread T0 at offset 416 in frame
#0 0x7ff8129fa82f in GMA<logistic>::solve() [clone ._omp_fn.0] ddhazard/GMA_solver.cpp:83
This frame has 5 object(s):
[32, 40) 'dest'
[96, 104) 'src'
[160, 176) 'ans'
[224, 384) 'my_X_cross'
[416, 576) '<unknown>' <== Memory access at offset 416 is inside this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope /data/gannet/ripley/R/test-3.5/RcppArmadillo/include/armadillo_bits/Mat_meat.hpp:1215 in arma::Mat<double>::Mat(double*, unsigned int, unsigned int, bool, bool)
Shadow bytes around the buggy address:
0x1000206648d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000206648e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000206648f0: 00 00 00 00 f1 f1 f1 f1 00 f2 f2 f2 f2 f2 f2 f2
0x100020664900: 00 f2 f2 f2 f2 f2 f2 f2 f8 f8 f2 f2 f2 f2 f2 f2
0x100020664910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100020664920: 00 00 00 00 f2 f2 f2 f2[f8]f8 f8 f8 f8 f8 f8 f8
0x100020664930: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f3 f3 f3 f3
0x100020664940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100020664950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100020664960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100020664970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==33791==ABORTING
The WRITE that causes the error is in the dynamichazard/src/ddhazard/GMA_solver.cpp and particularly this OpenMP block
#ifdef _OPENMP
int n_threads = std::max(1, std::min(omp_get_max_threads(),
(int)r_set.n_elem / 1000 + 1));
#pragma omp parallel num_threads(n_threads) if(n_threads > 1)
{
#endif
arma::mat my_X_cross(q, q, arma::fill::zeros);
#ifdef _OPENMP
#pragma omp for schedule(static)
#endif
for(arma::uword i = 0; i < r_set.n_elem; i++){
auto trunc_eta = T::truncate_eta(
is_event[i], eta[i], exp(eta[i]), at_risk_length[i]);
h_1d[i] = w[i] * T::d_log_like(
is_event[i], trunc_eta, at_risk_length[i]);
double h_2d_neg = - w[i] * T::dd_log_like(
is_event[i], trunc_eta, at_risk_length[i]);
sym_mat_rank_one_update(h_2d_neg, X_t.unsafe_col(i), my_X_cross);
}
#ifdef _OPENMP
#pragma omp critical(gma_lock)
{
#endif
X_cross += my_X_cross;
#ifdef _OPENMP
}
}
#endif
As far as I can tell, the error is at the X_t.unsafe_col(i) call in the call to sym_mat_rank_one_update. The declaration of the function is
void sym_mat_rank_one_update(const double, const arma::vec&, arma::mat&);
It should trigger a call to the arma::col<double> constructor in line 411 of include/armadillo_bits/Col_meat.hpp which inherit the arma::mat<double> constructor in line 1215 of include/armadillo_bits/Mat_meat.hpp. I gather this is where the 4 bit write occurs with one of the unsigned int since the arma::mat<double> constructor is
template<typename eT>
inline
Mat<eT>::Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem, const bool strict)
: n_rows ( aux_n_rows )
, n_cols ( aux_n_cols )
, n_elem ( aux_n_rows*aux_n_cols )
, vec_state( 0 )
, mem_state( copy_aux_mem ? 0 : ( strict ? 2 : 1 ) )
, mem ( copy_aux_mem ? 0 : aux_mem )
{
arma_extra_debug_sigprint_this(this);
if(copy_aux_mem == true)
{
init_cold();
arrayops::copy( memptr(), aux_mem, n_elem );
}
}
where
template<typename eT>
class Mat : public Base< eT, Mat<eT> >
{
public:
typedef eT elem_type; //!< the type of elements stored in the matrix
typedef typename get_pod_type<eT>::result pod_type; //!< if eT is std::complex<T>, pod_type is T; otherwise pod_type is eT
const uword n_rows; //!< number of rows (read-only)
const uword n_cols; //!< number of columns (read-only)
const uword n_elem; //!< number of elements (read-only)
const uhword vec_state; //!< 0: matrix layout; 1: column vector layout; 2: row vector layout
const uhword mem_state;
...
See include/armadillo_bits/Mat_bones.hpp and notice that arma::uword is unsigned int. However, I cannot figure out why this would cause a stack-use-after-scope.
A similar error is in the Morpho package. See the current CRAN log here and src/createL.cpp.
Setup
The above check is on CRAN. As far as I can tell, it is with gcc 7.2 on Fedora 26 with the following config.site used to build R
CXX="g++ -fsanitize=address,undefined,bounds-strict -fno-omit-frame-pointer"
CFLAGS="-g -O2 -Wall -pedantic -mtune=native -fsanitize=address"
FFLAGS="-g -O2 -mtune=native"
FCFLAGS="-g -O2 -mtune=native"
CXXFLAGS="-g -O2 -Wall -pedantic -mtune=native"
MAIN_LDFLAGS=-fsanitize=address,undefined
Further, the following ~/.R/Makevars is used
CC = gcc -std=gnu99 -fsanitize=address,undefined -fno-omit-frame-pointer
F77 = gfortran -fsanitize=address
FC = gfortran -fsanitize=address
FCFLAGS = -g -O2 -mtune=native -fbounds-check
FFLAGS = -g -O2 -mtune=native -fbounds-check
The error does not happen with clang 5.0.0 and valgrind on the same machine. Further, I cannot reproduce them on a local Ubuntu 17.04 with gcc version 6.3 and clang version 4.0.0.
Minimal, Complete, and Verifiable example
I will work on making one.

In WinDbg commands, how can I refer to a register with the same name as a global variable?

Suppose I want to debug this program using the WinDbg, cdb, or ntsd debuggers for Windows:
/* test.c */
#include <stdio.h>
int rip = 42;
int main(void)
{
puts("Hello world!");
return (0);
}
I compile the program for AMD64 and run it under WinDbg. I set a breakpoint at main(), and when the breakpoint hits, I want to inspect the value at the RIP register (program counter), and the memory around that value if the value is treated as a pointer.
I can see the value of the register directly with r rip, but when I try to look at the memory around that address, WinDbg shows me a different address! Having read the symbols in test.pdb, WinDbg sees that rip is a global variable declared in the C code and shows me the memory around &rip.
0:000> bu test!main
0:000> g
Breakpoint 0 hit
test!main:
00007ff6`de1868d0 4883ec28 sub rsp,28h
0:000> r rip
rip=00007ff6de1868d0
0:000> db rip
00007ff6`de1f2000 2a 00 00 00 ff ff ff ff-01 00 00 00 00 00 00 00 *...............
00007ff6`de1f2010 01 00 00 00 02 00 00 00-ff ff ff ff ff ff ff ff ................
00007ff6`de1f2020 00 00 00 00 00 00 00 00-43 46 92 e5 1b df 00 00 ........CF......
00007ff6`de1f2030 bc b9 6d 1a e4 20 ff ff-00 00 00 00 00 00 00 00 ..m.. ..........
00007ff6`de1f2040 00 01 00 00 00 00 00 00-ca b0 1e de f6 7f 00 00 ................
00007ff6`de1f2050 00 00 00 00 00 80 00 00-00 00 00 00 00 80 00 00 ................
00007ff6`de1f2060 d0 66 fc c2 f2 01 03 00-ab 90 ec 5e 22 c0 b2 44 .f.........^"..D
00007ff6`de1f2070 a5 dd fd 71 6a 22 2a 15-00 00 00 00 00 00 00 00 ...qj"*.........
0:000> ? rip
Evaluate expression: 140698265264128 = 00007ff6`de1f2000
0:000> ? dwo(rip)
Evaluate expression: 42 = 00000000`0000002a
This is really annoying, but as long as I'm aware of it, it isn't a problem when manually reading data like this. But if I want to use the register value, for example in scripting the debugger, then there is no easy workaround:
0:000> bu test!main ".if (dwo(rip) == 0n42) { .echo Whoops! I don't want to get here! }"
0:000> g
Whoops! I don't want to get here!
test!main:
00007ff6`de1868d0 4883ec28 sub rsp,28h
This problem, that symbols in the program hide register names, makes things really difficult for me. An actual scenario this broke:
I wanted to set a breakpoint on CreateFileW(), a very commonly called Windows API function.
Since I only cared about one particular file, I wanted to inspect the filename, which is passed in the RCX register, and continue past the breakpoint unless the filename matched the file I wanted.
But I couldn't write this condition, because another module in the program defined a symbol foobar!rcx, and any references to rcx I make in the command to execute on the breakpoint refer to that global variable!
So how do I tell WinDbg that yes, I really meant to read the register? And what if I want to write that register? There must be a simple thing I am missing here.
As noted in passing by another question, you can put an at sign (#) in front of a register name to force it to be interpreted as a register or pseudo-register, bypassing the attempt to parse it as a hexadecimal number or a symbol.
Registers and Pseudo-Registers in MASM Expressions
You can use registers and pseudo-registers within MASM expressions. You can add an at sign (#) before all registers and pseudo-registers. The at sign causes the debugger to access the value more quickly. This at sign is unnecessary for the most common x86-based registers. For other registers and pseudo-registers, we recommend that you add the at sign, but it is not actually required. If you omit the at sign for the less common registers, the debugger tries to parse the text as a hexadecimal number, then as a symbol, and finally as a register.

Resources