Today my colleague fixed one bug related to out-of-boundary access of array: a hash function returns the selected index of the array, but the hash function’s return value is int
, so in corner case, when the hash value is overflow, it can become negative, and this will cause access an invalid element of the array. The lessons I learnt from this bug:
(1) Review the return value of hash function;
(2) Pay attention to the index when accessing array, is it possible to cause out-of-boundary access?
Category: Technology
How to obtain a big-endian CPU machine
Last week, I wanted to test whether a trivial function works OK on big-endian CPU. I have ARM
and X86_64
machines at hand, but both them are little-endian. After searching online, I come across Running a emulated SparcStation 20 with qemu-sparc, though I heard about qemu
before, but never used it, so wanted to give it a spin.
The installation of qemu
is straightforward, then I created a NetBSD-10.1-sparc
machine in just 3
steps (omit some configurations unneeded for me):
$ qemu-img create -f qcow2 ss20.image 4G
$ qemu-system-sparc -M SS-20 -m 256 -drive file=NetBSD-10.1-sparc.iso,bus=0,unit=2,media=cdrom,readonly=on -drive file=ss20.image,bus=0,unit=0,media=disk -full-screen -boot d
$ qemu-system-sparc -M SS-20 -m 256 -drive file=ss20.image,bus=0,unit=0,media=disk -full-screen -boot c
Then the machine booted successfully and met my requirement perfectly!
Test multi-thread program on one CPU
Today, I tested a multi-thread program on one CPU. The testbed is a FreeBSD
virtual machine, and from lscpu command, it has indeed one CPU:
$ lscpu
Architecture: aarch64
Byte Order: Little Endian
Total CPU(s): 1
Model name: Apple Unknown CPU r0p0 (midr: 610f0000)
The multi-thread program is simple too, just 4
threads add one global variable, and the correct result should be 400000
in every run. If the result is not 400000
, exit the program:
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
#define THREAD_NUM 4
#define SUM_LOOP_SIZE 100000
uint64_t sum;
void *
thread(void *arg)
{
for (int i = 0; i < SUM_LOOP_SIZE; i++) {
sum++;
}
return NULL;
}
int
main()
{
pthread_t tid[THREAD_NUM];
uint64_t counter = 0;
while (1) {
counter++;
for (int i = 0; i < THREAD_NUM; i++) {
int ret = pthread_create(&tid[i], NULL, thread, NULL);
if (ret != 0) {
fprintf(stderr, "Create thread error: %s", strerror(ret));
return 1;
}
}
for (int i = 0; i < THREAD_NUM; i++) {
int ret = pthread_join(tid[i], NULL);
if (ret != 0) {
fprintf(stderr, "Join thread error: %s", strerror(ret));
return 1;
}
}
if (sum != THREAD_NUM * SUM_LOOP_SIZE) {
fprintf(stderr, "Exit after running %" PRIu64 " times, sum=%" PRIu64 "\n", counter, sum);
return 1;
}
sum = 0;
}
return 0;
}
Built and run the program:
$ ./multi_thread_one_cpu
Exit after running 17273076 times, sum=200000
$ ./multi_thread_one_cpu
Exit after running 1539708 times, sum=100000
Change “uint64_t sum;
” to “volatile uint64_t sum;
“, compile and run again:
$ ./multi_thread_one_cpu
Exit after running 20 times, sum=200000
$ ./multi_thread_one_cpu
Exit after running 50 times, sum=200000
Exit much faster.
In summary, when there are multiple threads access same variable, always use lock. P.S., the code can be found here.
Fix a weird “undefined symbol” issue
Today I met a weird “undefined symbol” issue, i.e., I built a program successfully on one machine, but after transferring it to another machine, it reported following error during running:
......
... symbol lookup error: xxxxxx: undefined symbol: LZ4F_compressFrameBound
from the output of ldd
, all libraries are there. After some time of debugging, I found the reason is the build machine and running machine have different versions of the librdkafka
library. After upgrading the librdkafka
library from build machine to the same version as running machine’s, the issue is fixed.
The shortcut keys for perf-report command
I am not sure it is only me, but I can’t find any document to introduce the shortcut keys for perf-report command. After executing perf report
, press h
will show the shortcut keys:
If you want to filter some symbols, press /
:
To remove filter, you should press / + ENTER
, instead of pressing q/ESC
:
Otherwise you will exit perf-report
program (Because the filtered symbols screen is actually the main screen when you run perf report
):