For various reasons I am verifying a program that attempts to read from a pointer with an offset of 0:
int x = (*(z + 0)).ssl_int;
When verifying this in VST, the context has as an assumption that there is a value on the heap at this location:
data_at Tsh (Tunion _sslval noattr) (inr x2) z
However, when trying to run forward over the read, the proof gets stuck with the error:
It is not obvious how to move forward here. ...
But the same read goes through fine if I adjust my precondition to be
data_at Tsh (tarray (Tunion_sslval noattr) 1) [(inr x2)] z
or change the source code such that the read is instead:
int x = (*z).ssl_int;
Is there a way to verify this program without changing the source code or the program specification? How can I make the read go through?
Related
So I am trying to use this built-in UART function (from the Vitis SDK from Xilinix) to determine if there is a valid byte to read over UART. I created this function to return 1 if there was a byte to read or 0 if there wasn't
u32 UartHasMessage(void){
if(XUartPs_IsReceiveData(&XUartPs_Main)){
return 1;
}
else{
return 0;
}
}
However, even when there is a byte to read over UART, this function always returns false.
The weird behavior I am experiencing is when I step through the code using the debugger, I call UartHasMessage() to check if there is a byte to read, and it returns false, but in the next line I call a function to read a byte over UART and that contains the correct byte I sent over the host.
u32 test - UartHasMessage();
UartGetByte(&HostReply);
How come this UartHasMessage always returns false, but then in the next line I am able to read the byte correctly?
Caveat: Without some more information, this is a bit speculative and might be a comment, but it is too large for that.
The information below comes from the Xilinx documentation on various pages ...
XUartPs_RecvByte will block until a byte is ready. So, no need to call XUartPs_IsReceiveData directly (I think that XUartPS_RecvByte calls it internally).
A web search on XUartPs_Main came up with nothing, so we'd need to see the definition you have.
Most Xilinx documentation uses UART_BASEADDRESS:
#define UART_BASEADDR XPAR_XUARTPS_0_BASEADDR
I found a definition:
#define XPAR_XUARTPS_0_BASEADDR 0xE0001000
You might be better off using a more standard method, such as calling the XUartPs_LookupConfig function to get the configuration table entry which has all relevant values.
I'm guessing that you created the XUartPS_Main definition.
But, based on what you posted, (needing &XUartPS_Main instead of XUartPS_Main), it is linked/loaded at the exact address of the UART register bank. Let's assume that address is (e.g.) 0x10000. So, we might have:
u32 XUartPS_Main __attribute__(at(0x10000));
The at is an extension that some build systems support (e.g. arm) that forces the variable to be loaded at a given address. So, let's assume we have that (even if the mechanism is slightly different (e.g.):
__attribute__((section(".ARM.__at_0x10000")))
The definition of XUARTPS_SR_OFFSET is:
#define XUARTPS_SR_OFFSET 0x002CU
Offsets are [typically] byte offsets.
Given:
#define XUartPs_IsReceiveData(BaseAddress) \
!((Xil_In32((BaseAddress) + XUARTPS_SR_OFFSET) & \
(u32)XUARTPS_SR_RXEMPTY) == (u32)XUARTPS_SR_RXEMPTY)
Now if the definition of XUartPS_Main uses u32 [as above], we may have a problem because XUARTPS_SR_OFFSET will be treated as a u32 index and not a byte offset. So, it will access the wrong address.
So, try:
XUartPs_IsReceiveData((unsigned char *) &XUartPs_Main)
But, if it were me, I'd rework things to use Xilinx's standard definitions.
UPDATE:
Hi so XUartPs_main is defined as static XUartPs XUartPs_Main; I use it in a variety of functions such as a function to send bytes over uart and I call it by its address like I did with this function, all my other functions work as expected except this one. Is it possible it is something to do with the way the fifo works? –
29belgrade29
No, not all the API functions are the same.
The struct definition is [I synthesized this from the API doc]:
typedef struct {
u16 DeviceId; // Unique ID of device.
u32 BaseAddress; // Base address of device (IPIF)
u32 InputClockHz;
} XUartPs;
Somewhere in your code you had to initialize this with:
XUartPs_Main = XUartPs_ConfigTable[my_device_id];
Or, with:
XUartPs_Main = *XUartPs_LookupConfig(my_device_id);
If an API function is defined as (e.g.):
void api_dosomething(XUartPs_Config *cfg,...)
Then, you call it with:
api_dosomething(&XUartPs_Main,...);
So, most functions probably take such a pointer.
But, XUartPs_IsReceiveData does not want a pointer to a XUartPs_Config struct. It wants a base address. This is:
XUartPs_Main.BaseAddress
So, you want:
XUartPs_IsReceiveData(XUartPs_Main.BaseAddress)
In the project I'm currently working on (in C), we're currently
keeping a hash table of some opaque objects. We're using the DPDK for
I/O in our app (version 16.07.2, unfortunately), and we're using the
rte_hash code for hashing our object. Trouble is, the objects we want
to hash have weird, non-rounded sizes like say 83 (or 18 as in the
example below), and address sanitizer complains about
heap-buffer-overflow (on read) - trying to read bytes after the end of
the region:
==4926==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300007a9c0 at pc 0x000000451573 bp 0x7fff69175040 sp 0x7fff69175030
READ of size 4 at 0x60300007a9c0 thread T10ESC[1mESC[0m
#0 0x451572 in __rte_jhash_2hashes /path/to/../dpdk/usr/include/dpdk/rte_jhash.h:155
#1 0x452bb6 in rte_jhash_2hashes /path/to/../dpdk/usr/include/dpdk/rte_jhash.h:266
#2 0x452c75 in rte_jhash /path/to/../dpdk/usr/include/dpdk/rte_jhash.h:309
0x60300007a9c2 is located 0 bytes to the right of 18-byte region [0x60300007a9b0,0x603
00007a9c2)
As far as I can tell, the problem is here in rte_jhash.h (see here for
code in the latest DPDK, it's unchanged as far as I can tell:
http://dpdk.org/doc/api/rte__jhash_8h_source.html):
case 6:
b += k[1] & LOWER16b_MASK; a += k[0]; break;
The code reads k[1] as a uint32_t, and then ANDs the value so that the
last 2 bytes are discarded. As far as I can tell, address sanitizer
complains about the uint32_t read, when only the first 2 bytes are
actually marked as readable. This makes sense, but the rte_hash code
boasts that it can use keys of any size. So my question is - is this
problem theoretical only? Or would it be possible to cause a crash with
this, maybe with a weird sized object that happens to be at the end of
a page? We're running on x86-64.
A few months ago, a change in the DPDK added something in the comments about this (see http://dpdk.org/browse/dpdk/commit/lib/librte_hash?id=0c57f40e66c8c29c6c92a7b0dec46fcef5584941), but I would've expected the wording to be more harsh if a crash was possible.
UPDATE: sample code to reproduce the warning. Compile with:
gcc -o jhash_malloc -Wall -g -fsanitize=address -I /path/to/dpdk/x86_64-native-linuxapp-gcc/include/ jhash_malloc.c
And the code:
#include <stdio.h>
#include <rte_jhash.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
size_t strSize = 13;
char *str = malloc(strSize);
memset(str, 'g', strSize);
uint32_t hval = rte_jhash(str, strSize, 0);
printf("Hash of %s (size %zu) is %u\n", str, strSize, hval);
free(str);
return 0;
}
UPDATE2: And the output:
==27276==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000effc at pc 0x000000401315 bp 0x7ffdea936f80 sp 0x7ffdea936f70
READ of size 4 at 0x60200000effc thread T0
#0 0x401314 in __rte_jhash_2hashes /home/stefan/src/dpdk-17.08/x86_64-native-linuxapp-gcc/include/rte_jhash.h:165
#1 0x402771 in rte_jhash_2hashes /home/stefan/src/dpdk-17.08/x86_64-native-linuxapp-gcc/include/rte_jhash.h:266
#2 0x402830 in rte_jhash /home/stefan/src/dpdk-17.08/x86_64-native-linuxapp-gcc/include/rte_jhash.h:309
#3 0x4028e7 in main /home/stefan/src/test/misc/jhash_malloc.c:12
#4 0x7f470cb1f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#5 0x400978 in _start (/home/stefan/src/test/misc/jhash_malloc+0x400978)
0x60200000effd is located 0 bytes to the right of 13-byte region [0x60200000eff0,0x60200000effd)
UPDATE3: the original Jenkins hash code seems to be this: http://burtleburtle.net/bob/c/lookup3.c. There is an interesting comment in the source that suggests the asan / valgrind warning can be ignored:
* "k[2]&0xffffff" actually reads beyond the end of the string, but
* then masks off the part it's not allowed to read. Because the
* string is aligned, the masked-off tail is in the same word as the
* rest of the string. Every machine with memory protection I've seen
* does it on word boundaries, so is OK with this. But VALGRIND will
* still catch it and complain. The masking trick does make the hash
* noticably faster for short strings (like English words).
Of course, if you want to hash parts of a larger object that's malloc-ed, you could still be in trouble.
You are right, if the key you are passing to rte_jhash() is happened to be at the end of the page and the next page if not readable, the app will crash. The commit you are referring to is basically fixing it, but in the documentation, not in the code.
The solution would be either to:
make sure all the keys in your code are aligned and padded to the 4 bytes; (also see notes below)
OR fix the key length in your code to be multiply of 4;
OR copy-paste rte_jhash() in your project and fix it and later send the fix to the DPDK mailing list.
Note 1: usually structures in C are already aligned and padded to the largest primitive data type of a structure. So this explicit padding should not cause any performance/memory issues, unless the structure is packed.
Note 2: if the keys are manages by DPDK library (i.e. you use DPDK Cuckoo Hash library), the storage for the keys will be aligned and padded internally, so there is nothing to be worried about.
Overall, if your keys are managed externally (i.e. by another process, or you receive those from network etc), it might be a real issue. Otherwise, there are quite easy ways to fix those...
I am trying to get call stack backtrace at my assert/exception handler. Can't include "execinfo.h" therefore can't use int backtrace(void **buffer, int size);.
Also, tried to use __builtin_return_address() but acording to :http://codingrelic.geekhold.com/2009/05/pre-mortem-backtracing.html
... on some architectures, including my beloved MIPS, only __builtin_return_address(0) works.MIPS has no frame pointer, making it difficult to walk back up the stack. Frame 0 can use the return address register directly.
How can I reproduce full call stack backtrace?
I have successfully used the method described here, to get a call trace from stack on MIPS32.
You can then print out the call stack:
void *retaddrs[16];
int n, i;
n = get_call_stack_no_fp (retaddrs, 16);
printf ("CALL STACK: ");
for (i = 0; i < n; i++) {
printf ("0x%08X ", (uintptr_t)retaddrs[i]);
}
printf ("\r\n");
... and if you have the ELF file, then use the addr2line to convert the return addresses to function names:
addr2line -a -f -p -e xxxxxxx.elf addr addr ...
There are of course many gotchas, when using a method like this, including interrupts and exception handlers or results of code optimization. But nevertheless, it might be helpful sometimes.
I have successfully used the method suggested by #Erki A and described here.
Here is a short summary of the method:
The problem:
get a call stack without a frame pointer.
Solution main idea:
conclude from the assembly code what the debugger understood from debug info.
The information we need:
1. Where the return address is kept.
2. What amount the stack pointer is decremented.
To reproduce the whole stack trace one need to:
1. Get the current $sp and $ra
2. Scan towards the beginning of the function and look for "addui
sp,sp,spofft" command (spofft<0)
3. Reprodece prev. $sp (sp- spofft)
4. Scan forward and look for "sw r31,raofft(sp)"
5. Prev. return address stored at [sp+ raofft]
Above I described one iteration. You stop when the $ra is 0.
How to get the first $ra?
__builtin_return_address(0)
How to get the first $sp?
register unsigned sp asm("29");
asm("" : "=r" (sp));
***Since most of my files compiled with micro-mips optimisation I had to deal with micro-mips-ISA.
A lot of issues arose when I tried to analyze code that compiled with microMips optimization(remember that the goal at each step is to reproduce prev. ra and prev. sp):
It makes things a bit more complicated:
1. ra ($31) register contain unaligned return address.
You may find more information at Linked questions.
The unaligned ra helps you understand that you run over different
ISA(micro-mips-isa)
2. There are functions that do not move the sp. You can find more
information [here][3].
(If a "leaf" function only modifies the temporary registers and returns
to a return statement in its caller's code, then there is no need for
$ra to be changed, and there is no need for a stack frame for that
function.)
3. Functions that do not store the ra
4. MicroMips instructions can be both - 16bit and 32bit: run over the
commnds using unsinged short*.
5. There are functions that perform "addiu sp, sp, spofft" more than once
6. micro-mips-isa has couple variations for the same command
for example: addiu,addiusp.
I have decided to ignore part of the issues and that is why it works for 95% of the cases.
It seems like my previous post but issue here is different ..
This is the C structure for problem -
typedef struct ip_esp_private { /* keep track of things privately */
u_int32_t type;
u_int32_t ivlen;
u_int32_t icvlen;
u_int32_t keylen; /* length of "Encryption key */
u_int32_t akeylen; /*length of authn key */
u_int32_t key[0]; /* encryption key and authentication key both */
} esp_private;
The values are provided to structure contents at run time as follows -
case 'k': /* Key */
length = stringargument(arg, &temp);
priv->keylen = length;
priv = (esp_private *)realloc(priv,
sizeof(esp_private)+/*length*/priv->keylen);
/*This one is edited */
// if(priv->akeylen)
// memmove(&priv->key[priv->keylen],
// &priv->key[0],priv->akeylen);
/*These three are commented*/
memcpy(&priv->key[0], temp, priv->keylen);
pack->private = priv;
pack->modified |= ESP_MOD_KEY;
break;
case 'K': /* Authentication Key */
length = stringargument(arg, &temp);
priv->akeylen = length; // marked line(explained below)
priv = (esp_private *)realloc(priv,
sizeof(esp_private)+/*length*/priv->keylen+priv->akeylen);
/*this one edited too */
memcpy(&priv->key[priv->keylen/sizeof(u_int32_t)],
temp,priv->akeylen);
pack->private = priv;
pack->modified |= ESP_MOD_KEY;
Now there is a function which uses the value of authentication key.
The relevant part of the function is -
if (!epriv->akeylen) {
key = &fakekey;
keylen = 1;
} else {
key = (u_int8_t *)malloc(epriv->akeylen);
memcpy(key,&epriv->key[epriv->keylen/sizeof(u_int32_t)]
,epriv->akeylen);
Now when I tried to run the following program , getting this error about which I have no idea.
sendip: malloc.c:3574: mremap_chunk: Assertion `((size + offset)
& (mp_.pagesize-1)) == 0' failed.
I think may be there is a error in function part but what exactly it is I am not sure,
because when I comment the marked line (mentioned above) the akeylen is null
so taking that fakekey value and program runs fine.
Edit 1:
I have edited the code at three places (also edited in the above code ).
Now program works but an inconsistent output occurs.
Input :
Encryption key - qwerty
Authentication key - abcdef
Output:
Encryption key - qwerab
Authentication key - abcdef
The situation is more clear now .
The problem it means is surely there at realloc statements .
Please suggest on this.
Initially I added length at both realloc statements but now I changed it to priv->keylen at first place and priv->keylen+priv->akeylen at secone place.
But something still needs to be improved
Why this is overwriting ???
Since the key[0] struct hack appears to contain space for both keys, you'll need to allocate memory for both, too. In both cases ('k' and 'K' )
priv = realloc(priv, sizeof *priv +priv->keylen+priv->akeylen);
When concatenating the two keys, it is easiest to cast the u_int32_t key into a character pointer and do arithmatic on that one:
memcpy ( priv->key, source1, sizeofsource1);
/* and */
memcpy ( ((char*) priv->key) +priv->keylen, source2, sizeofsource2);
[and similar for the memmove()]
The rest of the casts in your program can be removed.
If you get assertion failures from within malloc, the problem is outside. The assertion is not about the parameters passed to malloc, but about the state of the memory, which is corrupted. This means that you previously wrote to a memory area you were not supposed to write. So even if you provided a proper traceback (using gdb for instance), this would not point you to the source of the problem. There are a number of tools for debugging memory problems. One of the most widely used tools is valgrind. It will make your program horribly slow and show you tons of possible problems by looking at every single memory access. Another more lightweight tool is mudflap, which is to be linked against. A very basic approach to narrowing down the problem is to add assert(condition) statements to your code and hope that you fail earlier. Sometimes you can solve this problem by looking at every single memory access in your code and ensure that it is not out of bounds (or if you are unsure, add an assertion statement).
This code intermittently works. It's running on a small microcontroller. It will work fine even after restarting the processor, but if I change some part of the code, it breaks. This makes me think that it's some kind of pointer bug or memory corruption. What's happening is the coordinate, p_res.pos.x is sometimes read as 0 (the incorrect value) and 96 (the correct value) when it is passed to write_circle_outlined. y seems to be correct most of the time. If anyone can spot anything obviously wrong please point it out!
int demo_game()
{
long int d;
int x, y;
struct WorldCamera p_viewer;
struct Point3D_LLA p_subj;
struct Point2D_CalcRes p_res;
p_viewer.hfov = 27;
p_viewer.vfov = 32;
p_viewer.width = 192;
p_viewer.height = 128;
p_viewer.p.lat = 51.26f;
p_viewer.p.lon = -1.0862f;
p_viewer.p.alt = 100.0f;
p_subj.lat = 51.20f;
p_subj.lon = -1.0862f;
p_subj.alt = 100.0f;
while(1)
{
fill_buffer(draw_buffer_mask, 0x0000);
fill_buffer(draw_buffer_level, 0xffff);
compute_3d_transform(&p_viewer, &p_subj, &p_res, 10000.0f);
x = p_res.pos.x;
y = p_res.pos.y;
write_circle_outlined(x, y, 1.0f / p_res.est_dist, 0, 0, 0, 1);
p_viewer.p.lat -= 0.0001f;
//p_viewer.p.alt -= 0.00001f;
d = 20000;
while(d--);
}
return 1;
}
The code for compute_3d_transform is:
void compute_3d_transform(struct WorldCamera *p_viewer, struct Point3D_LLA *p_subj, struct Point2D_CalcRes *res, float cliph)
{
// Estimate the distance to the waypoint. This isn't intended to replace
// proper lat/lon distance algorithms, but provides a general indication
// of how far away our subject is from the camera. It works accurately for
// short distances of less than 1km, but doesn't give distances in any
// meaningful unit (lat/lon distance?)
res->est_dist = hypot2(p_viewer->p.lat - p_subj->lat, p_viewer->p.lon - p_subj->lon);
// Save precious cycles if outside of visible world.
if(res->est_dist > cliph)
goto quick_exit;
// Compute the horizontal angle to the point.
// atan2(y,x) so atan2(lon,lat) and not atan2(lat,lon)!
res->h_angle = RAD2DEG(angle_dist(atan2(p_viewer->p.lon - p_subj->lon, p_viewer->p.lat - p_subj->lat), p_viewer->yaw));
res->small_dist = res->est_dist * 0.0025f; // by trial and error this works well.
// Using the estimated distance and altitude delta we can calculate
// the vertical angle.
res->v_angle = RAD2DEG(atan2(p_viewer->p.alt - p_subj->alt, res->est_dist));
// Normalize the results to fit in the field of view of the camera if
// the point is visible. If they are outside of (0,hfov] or (0,vfov]
// then the point is not visible.
res->h_angle += p_viewer->hfov / 2;
res->v_angle += p_viewer->vfov / 2;
// Set flags.
if(res->h_angle < 0 || res->h_angle > p_viewer->hfov)
res->flags |= X_OVER;
if(res->v_angle < 0 || res->v_angle > p_viewer->vfov)
res->flags |= Y_OVER;
res->pos.x = (res->h_angle / p_viewer->hfov) * p_viewer->width;
res->pos.y = (res->v_angle / p_viewer->vfov) * p_viewer->height;
return;
quick_exit:
res->flags |= X_OVER | Y_OVER;
return;
}
Structure for the results:
typedef struct Point2D_Pixel { unsigned int x, y; };
// Structure for storing calculated results (from camera transforms.)
typedef struct Point2D_CalcRes
{
struct Point2D_Pixel pos;
float h_angle, v_angle, est_dist, small_dist;
int flags;
};
The code is part of an open source project of mine so it's okay to post a lot of code here.
I see some of your calculation depends on p_viewer->yaw, but I do not see any intialization for p_viewer->yaw. Is this your problem?
A couple of things that seem sketchy:
You can return from compute_3d_transform without setting many of the fields in p_res/res but the caller never checks for this situation.
You consistently read from res->flags without initializing it first.
Whenever the output differs, it possibly means some value is not initialized and the outcome depends on the garbage value present in a variable. Keeping that in mind, I looked for uninitialized variables. the structure p_res is not initialized.
if(res->est_dist > cliph)
goto quick_exit;
that means if condition may turn out to be true or false depending on what garbage value is stored in res->est_dist. When if condition turns out to true, it goes straight to quick_exit label and doesn't update p_res.pos.x. If condition turned out to be false then its updated.
When I used to program C, I would use a divide and conquer debugging technique for this kind of problem to try to isolate the offending operation (paying attention to whether the symptoms change as debugging code is added, which is indicative of dangling pointer type bugs).
Essentially, start with the first line where the value is known to be good (and prove that it is consistently good at that line). Then identify where is it known to be bad. Then approx. halfway between the two points insert a test to see if it's bad. If not, then insert a test halfway between the mid-point and the known bad location, if it is bad then insert a test halfway between the mid-point and the known good location, and so on.
If the line identified is itself a function call, this process can be repeated in that called function, and so on.
When using this kind of approach, it's important to minimize the amount of added code and the artificial "noise", which can create timing changes.
Use this if you don't have (or can't use) an interactive debugger, or if the problem does not manifest when using one.