Skip to content

Commit 4e3333c

Browse files
popcornmixpelwell
authored andcommitted
vclog: Use volatile to avoid memcpy optimisation
vclog works fine with -O1 but gives a bus error with -O2. If I can trust the backtrace it looks like gcc turned the copy-loop into a memcpy call... Program received signal SIGBUS, Bus error. __memcpy_generic () at ../sysdeps/aarch64/multiarch/../memcpy.S:96 96 ldr A_l, [src] (gdb) where src=0x7fb6dc4164 "\247\200 \001", src@entry=0x1 <error: Cannot access memory at address 0x1>, n=376432, n@entry=376444) at /home/hias/libreelec/libreelec-master/build.LibreELEC-RPi4.aarch64-12.0-devel/build/bcm2835-utils-a843bed/vclog/vcdbg.c:731 at /home/hias/libreelec/libreelec-master/build.LibreELEC-RPi4.aarch64-12.0-devel/build/bcm2835-utils-a843bed/vclog/vcdbg.c:267 (gdb) up src=0x7fb6dc4164 "\247\200 \001", src@entry=0x1 <error: Cannot access memory at address 0x1>, n=376432, n@entry=376444) at /home/hias/libreelec/libreelec-master/build.LibreELEC-RPi4.aarch64-12.0-devel/build/bcm2835-utils-a843bed/vclog/vcdbg.c:731 731 *dest = *src++; (gdb) list 726 // Manually copy bytes before first boundary 727 size_t bytes_to_manually_copy = 728 n < bytes_until_boundary ? n : bytes_until_boundary; 729 n -= bytes_to_manually_copy; 730 while (bytes_to_manually_copy--) { 731 *dest = *src++; 732 dest++; 733 } 734 735 // return if we copied all of n (gdb) p bytes_to_manually_copy $1 = 11 (gdb) p src $2 = 0x7fb6dc4164 "\247\200 \001"
1 parent 082f1ff commit 4e3333c

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

vclog/vcdbg.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static bool parse_and_print_assert_msg(char *txt, size_t size_of_text,
164164
src address is not a aligned to a boundary at the start of memcpy (and at the
165165
end of the region copied)
166166
dest & src MUST have the same alignment */
167-
static void memcpy_vc_memory(char *restrict dest, const char *restrict src,
167+
static void memcpy_vc_memory(char *restrict dest, const volatile char *restrict src,
168168
size_t n);
169169

170170
/******************************************************************************
@@ -715,8 +715,12 @@ static bool vc_write_ptr_within_current_msg(
715715
return true;
716716
}
717717

718-
/*****************************************************************************/
719-
static void memcpy_vc_memory(char *restrict dest, const char *restrict src,
718+
/********************************************************************************/
719+
/* Note: gcc with -O2 or higher may replace most of this code with memcpy */
720+
/* which causes a bus error when given an insufficiently aligned mmap-ed buffer */
721+
/* Using volatile disables that optimisation */
722+
/********************************************************************************/
723+
static void memcpy_vc_memory(char *restrict dest, const volatile char *restrict src,
720724
size_t n) {
721725
// Calculate non-boundary aligned bytes at start/end of region
722726
size_t src_offset = (uintptr_t)src % boundary;
@@ -739,7 +743,7 @@ static void memcpy_vc_memory(char *restrict dest, const char *restrict src,
739743
// memcpy centre region starting/ending on boundaries
740744
int bytes_to_memcpy = n - bytes_over_end_boundary;
741745
if (bytes_to_memcpy) {
742-
memcpy(dest, src, bytes_to_memcpy);
746+
memcpy(dest, (const void *)src, bytes_to_memcpy);
743747
dest += bytes_to_memcpy;
744748
src += bytes_to_memcpy;
745749
n -= bytes_to_memcpy;

0 commit comments

Comments
 (0)