Skip to content

Instantly share code, notes, and snippets.

@rfjakob
Created October 26, 2016 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rfjakob/d01281c737db38075767f90bf03fc475 to your computer and use it in GitHub Desktop.
Save rfjakob/d01281c737db38075767f90bf03fc475 to your computer and use it in GitHub Desktop.
Reproducer for the bug that tmpfs returns null bytes for truncated files
// Compile and run:
// gcc -Wall -lpthread truncate_read.c && ./a.out
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
int fd;
int l = 10*1024*1024;
pthread_t tid[2];
void* read_thread(void *arg){
int o,n;
char b;
for(o=l; o>0; o--) {
b = 'a';
n = pread(fd, &b, 1, o);
if(n==0) {
continue;
}
if(b != 'x') {
printf("wrong data: %x\n", b);
}
}
return NULL;
}
void* truncate_thread(void *arg){
// Parent = Truncater
int o,n;
// "3" seems to be the sweet spot to trigger the most errors.
for(o=l; o>0; o-=3) {
n = ftruncate(fd, o);
if(n!=0) {
perror("ftruncate err");
}
}
return NULL;
}
int main(int argc, char *argv[]) {
fd = open("/dev/shm/x", O_RDWR | O_TRUNC | O_CREAT, 0666);
if(fd < 0) {
printf("open failed\n");
exit(1);
}
char* x = malloc(l);
memset(x, 'x', l);
write(fd, x, l);
pthread_create(&(tid[0]), NULL, &read_thread, NULL);
pthread_create(&(tid[1]), NULL, &truncate_thread, NULL);
void *res;
pthread_join(tid[0], &res);
pthread_join(tid[1], &res);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment