2

I have a program that writes in some FPGA memory. When the program is compiled with optimizations (either O1, O2 or O3) it crashes with a bus error. However there is no crash when the program is compiled without optimizations.

Here is a minimal example which crashes:

void set_reg(const uint32_t *data)
{
    uint32_t val = data[0];
    dvm.write32(dac_map, 0, static_cast<uint32_t>(8192 * cos(val))); // crash
}

When I add volatile there is no more crash:

void set_reg(const uint32_t *data)
{
    volatile uint32_t val = data[0];
    dvm.write32(dac_map, 0, static_cast<uint32_t>(8192 * cos(val))); // no crash
}

If I remove the call to cos there is no problem.

This seems related to GCC: program doesn't work with compilation option -O3. When I add the flag -ffloat-store the program don't crash.

However, on the actual code which is more complicated, adding the flag -ffloat-store doesn't solve the problem.

I don't understand the kind of optimization GCC does and how this leads to a SIGBUS. If anyone could explain that, it would be useful for debugging.

Thank you.


NB:

1) GCC version is arm-linux-gnueabihf-g++ (Ubuntu/Linaro 5.3.1-14ubuntu2) 5.3.1 20160413

2) The function write32 is defined as

void write32(MemMapID id, uint32_t offset, uint32_t value) 
{
    ASSERT_WRITABLE
    *(volatile uintptr_t *) (GetBaseAddr(id) + offset) = value;
}
Community
  • 1
  • 1
  • On the present architecture `uintptr_t` should be equal to `uint32_t`. If I just use `*(volatile uintptr_t) (GetBaseAddr(id) + offset) = value` I get an error `invalid type argument of unary ‘*’ (have ‘uintptr_t {aka unsigned int}’)`. – user3719401 Jun 22 '16 at 14:21
  • oops, @user3719401, I forgot what `uintptr_t` was for--still, I would correct that type cast to `volatile uint32_t *` for consistency – obataku Jun 22 '16 at 14:37
  • Actually `GetBaseAddr` returns an `uintptr_t` since on some architecture the virtual memory addresses may be encoded with an `uint64_t` for example. Using `uint32_t` works here (and leads to the same problem), but it will break if the program is compiled on a 64 bits machine for example. – user3719401 Jun 22 '16 at 14:51
  • anyhow, is `data` pointing to memory-mapped FPGA memory? do you have any assembly code to compare the working and broken examples? – obataku Jun 22 '16 at 15:08
  • No `data` is 'normal' memory only `dac_map` is pointing to the FPGA memory. I don't have any assembly code, I can try to generate some but I will have to build the code in a small `main()`. – user3719401 Jun 22 '16 at 15:16
  • okay, please let me know when you have a self-contained example demonstrating the problem! – obataku Jun 22 '16 at 17:03
  • also let us know what you find out using a memory debugger/sanitizer like Valgrind – obataku Jun 22 '16 at 17:19

0 Answers0