"Corrupted double-linked list" when using malloc() on a 2D array in a structure - malloc

I'm trying to make a small autoCompletion program.
I'm taking strings from a file and put them line by line in a 2D char type array.
This is my code :
Dictionnary.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Dictionnary.h"
int getDictionnarySize(FILE *theDictionnary)
{
size_t pos = ftell(theDictionnary);
fseek(theDictionnary, 0, SEEK_END);
size_t len = ftell(theDictionnary);
fseek(theDictionnary, pos, SEEK_SET);
return (len);
}
int getNbLines(char *buff)
{
int lines = 1;
int i = 0;
while (buff[i] != '\0')
{
if (buff[i] == '\n')
lines++;
i++;
}
return (lines);
}
int allocDictionnary(t_dictionnary *d, char *buff)
{
d->lines = getNbLines(buff) - 1;
int i;
char str[2048];
int len;
rewind(d->dico);
d->dictionnary = malloc(sizeof(*d->dictionnary) * d->lines);
for (i = 0; i <= d->lines; i++)
{
memset(str, 0, 2048);
fgets(str, 256, d->dico);
len = strlen(str);
printf("len = %d\n", len);
d->dictionnary[i] = malloc(sizeof(**d->dictionnary) * len);
if (d->dictionnary[i] == NULL)
return (1);
strcpy(d->dictionnary[i], str);
printf("String is : %s\n", d->dictionnary[i]);
}
return (0);
}
int initDictionnary(t_dictionnary *d)
{
int size;
char *buff;
if ((d->dico = fopen(d->theDictionnary, "r")) != NULL)
{
size = getDictionnarySize(d->dico);
buff = malloc(size + 1);
fread(buff, size, 1, d->dico);
allocDictionnary(d, buff);
fclose(d->dico);
}
else
{
return (1);
}
free(buff);
return (0);
}
int killDictionnary(char **theDictionnary, int size)
{
int i = 0;
while (i <= size)
{
free(theDictionnary[i]);
i++;
}
free(theDictionnary);
return (0);
}
Dictionnary.h
#ifndef __DICTIONNARRY_H__
# define __DICTIONNARY_H___
/* STRUCTURES */
typedef struct s_dictionnary
{
const char *theDictionnary;
FILE *dico;
char **dictionnary;
int lines;
} t_dictionnary;
/* PROTOTYPES */
int getDictionnarySize(FILE *theDictionnary);
int allocDictionnary(t_dictionnary *d, char *buff);
int initDictionnary(t_dictionnary *dico);
int getNbLines(char *buff);
int killDictionnary(char **theDictionnary, int size);
#endif /* __DICTIONNARY_H__ */
main.c
#include <stdlib.h>
#include <stdio.h>
#include "Dictionnary.h"
int main(int ac, char **av)
{
t_dictionnary d;
d.theDictionnary = "./miniDico";
initDictionnary(&d);
killDictionnary(d.dictionnary, d.lines);
return (0);
}
When I compile, i don't have any errors or warnings.
But when I run this I get :
*** Error in `./a.out': corrupted double-linked list: 0x0000000000f19550 ***
Valgrind result :
==4004== Memcheck, a memory error detector
==4004== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4004== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4004== Command: ./a.out
==4004==
==4004== Conditional jump or move depends on uninitialised value(s)
==4004== at 0x40095C: getNbLines (Dictionnary.c:22)
==4004== by 0x40098B: allocDictionnary (Dictionnary.c:34)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
len = 35
==4004== Invalid write of size 1
==4004== at 0x4C2D623: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x400AB8: allocDictionnary (Dictionnary.c:50)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d8723 is 0 bytes after a block of size 35 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x400A61: allocDictionnary (Dictionnary.c:47)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
==4004== Invalid read of size 1
==4004== at 0x4E7E1C2: vfprintf (in /usr/lib/libc-2.21.so)
==4004== by 0x4E84E38: printf (in /usr/lib/libc-2.21.so)
==4004== by 0x400AE5: allocDictionnary (Dictionnary.c:51)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d8723 is 0 bytes after a block of size 35 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x400A61: allocDictionnary (Dictionnary.c:47)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
String is : Paris, 458 boulevard Saint-Germain
len = 35
String is : Paris, 343 boulevard Saint-Germain
len = 44
String is : Marseille, 343 boulevard Camille Flammarion
len = 37
String is : Marseille, 29 rue Camille Desmoulins
len = 34
String is : Marseille, 1 chemin des Aubagnens
len = 25
String is : Paris, 12 rue des singes
len = 24
String is : Paris, 34 quai VoLtAiRe
len = 23
String is : Paris, 34 rue Voltaire
len = 33
String is : Lille, 120 boulevard Victor Hugo
len = 27
String is : Marseille, 50 rue Voltaire
len = 26
String is : Toulouse, 90 rue Voltaire
len = 30
String is : Strasbourg 84 rue du Bouclier
len = 42
String is : Marseille, 78 boulevard de la libération
len = 27
String is : Lille, 30 rue Victor Danel
len = 38
String is : Mont Saint Martin, 42 rue de Bordeaux
len = 47
String is : Mont de Marsan, 100 avenue Pierre de Coubertin
len = 35
String is : Strasbourg, 391 boulevard de Nancy
len = 38
String is : Lyon, 56 rue du Docteur Albéric Pont
len = 35
String is : Lyon, rue du Docteur Albéric Pont
len = 38
String is : 56 rue du Docteur Albéric Pont, Lyon
len = 19
String is : Lyon 56 grande rue
len = 24
String is : Lille, 90 rue d’Arras
len = 35
String is : Lille, 76 impasse Georges Pompidou
len = 25
==4004== Invalid write of size 8
==4004== at 0x400A62: allocDictionnary (Dictionnary.c:47)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d86b8 is 0 bytes after a block of size 184 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x4009C3: allocDictionnary (Dictionnary.c:40)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
==4004== Invalid read of size 8
==4004== at 0x400A7D: allocDictionnary (Dictionnary.c:48)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d86b8 is 0 bytes after a block of size 184 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x4009C3: allocDictionnary (Dictionnary.c:40)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
==4004== Invalid read of size 8
==4004== at 0x400AA4: allocDictionnary (Dictionnary.c:50)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d86b8 is 0 bytes after a block of size 184 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x4009C3: allocDictionnary (Dictionnary.c:40)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
==4004== Invalid read of size 8
==4004== at 0x400AD1: allocDictionnary (Dictionnary.c:51)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d86b8 is 0 bytes after a block of size 184 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x4009C3: allocDictionnary (Dictionnary.c:40)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
String is : Lyon, 2 allée des fleurs
==4004== Invalid read of size 8
==4004== at 0x400BF6: killDictionnary (Dictionnary.c:85)
==4004== by 0x400C53: main (main.c:11)
==4004== Address 0x51d86b8 is 0 bytes after a block of size 184 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x4009C3: allocDictionnary (Dictionnary.c:40)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
==4004==
==4004== HEAP SUMMARY:
==4004== in use at exit: 0 bytes in 0 blocks
==4004== total heap usage: 27 allocs, 27 frees, 2,289 bytes allocated
==4004==
==4004== All heap blocks were freed -- no leaks are possible
==4004==
==4004== For counts of detected and suppressed errors, rerun with: -v
==4004== Use --track-origins=yes to see where uninitialised values come from
==4004== ERROR SUMMARY: 54 errors from 8 contexts (suppressed: 0 from 0)

Maybe this loop causing troubles:
for (i = 0; i <= d->lines; i++)
It seems that it should be (I've changed stop condition):
for (i = 0; i < d->lines; i++)
otherwise you write behind allocated space...
UPDATE
Clarification:
Allocating array with d->dictionnary = malloc(sizeof(*d->dictionnary) * d->lines); gives you an arry with exactly d->lines elements. It starts from 0 index and last element could be accessed with d->lines-1 index. So when you use loop from 0 up to and including d->lines the very last loop cycle will write outside of array boundaries (i.e. to d->lines index). That's where you corrup your heap. Very often C runtime doesn't check for such errors and you will only see them on rare ocasions and probably far away from the code which caused them.
"corrupted linked list" is about heap corruption. Blocks allocated with malloc are usually chained into linked lists (this really depends on implementation of you memory allocator). So, when writing outside allocation boundaries - you can corrupt this list. Hence the complaint.

Related

mmap() system call linux 32-bit x86 NASM(i386)

I am trying to use mmap for my code but I dont have a clue to choose the values to store in the registers in pre interrupt processing. I picked up below part of code from somewhere. I am trying to print the return value (ig this will be stored in eax) after the interrupt but the value is negative(-14) which means the process is unsucessfull what should I change here?
mov ebx,0 ;address
mov edx,0x1 ;protection
mov esi,0x2 ;flags
mov edi,[file_descriptor];file descriptor
mov ecx,4096 ;size
mov ebp,0 ;offset is 0
mov eax,192 ;mmap instruction code(90)
int 0x80 ;For mmap
PutLInt eax ;printing the returned value after the system-call
I am getting strace output as:
strace ./a
execve("./a", ["./a"], 0x7ffcdf6517c0 /* 49 vars */) = 0
strace: [ Process PID=20342 runs in 32 bit mode. ]
read(0, 3
"3\n", 256) = 2
creat("input.txt", 0700) = 3
read(0, 4
"4\n", 20) = 2
write(3, "4\n", 2) = 2
read(0, 5
"5\n", 20) = 2
write(3, "5\n", 2) = 2
read(0, 6
"6\n", 20) = 2
write(3, "6\n", 2) = 2
write(1, "\n", 1
) = 1
write(1, "3", 13) = 1
write(1, "\n", 1
) = 1
write(1, "3", 13) = 1
write(1, "\n", 1
) = 1
mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0) = -1 EACCES (Permission denied)
write(1, "-", 1-) = 1
write(1, "1", 11) = 1
write(1, "3", 13) = 1
exit(0) = ?
+++ exited with 0 +++

Can't print string custom kernel operating system [duplicate]

I am developing a kernel in C and created something to print on screen on video memory. I expected that the first byte in video memory would be the character to print and the second byte tells the color. But my program has something different but it works!! It is very unexpected and unusual.
My kernel code -
#define VIDEO_MEM 0xb8000
void write_string( int colour, const unsigned char *string );
void main()
{
unsigned char *vid = (unsigned char*) VIDEO_MEM;
int i=0;
for (i = 0; i < 2000; i++)
{
*vid = ' ';
*(vid+2) = 0x1f;
vid += 2;
}
write_string(0x1f,"The Kernel has been loaded successfully!!");
}
void write_string( int colour, const unsigned char *string ) {
unsigned char *vid = (unsigned char*) VIDEO_MEM;
while(*string != 0)
{
*(vid) = *string;
*(vid+2) = colour;
++string;
vid+=2;
}
}
It prints the character on *vid and the color on *(vid+2) and then increments the vid by 2. It should then replace and print the next char on *(vid+2). So, the color should go but it still works.
Also, the color should be on *(vid+1)
When I use *(vid+1) instead of *(vid+2) to print the string, the screen shows down arrow characters (with ACII code 0x1f which I wanted to be the color) replacing the entire string.
Why does the code behave so unusual??
Can anyone help?
EDIT
I have edited my code and now it prints string. But another problem arose. I added a support for printing on particular line number. But now this shifts the string backwards by one character.
void write_string( int colour, const unsigned char *string, int pos ) {
unsigned char *vid = (unsigned char*) VIDEO_MEM;
vid+=pos*160;
while(*string != 0)
{
*vid = colour;
*(vid+1) = *string;
++string;
vid+=2;
}
}
So, If I tell it to print on line 10, it prints the first character on the last character of the 9th line and then continues.
I also have a character printing function that justs prints curly braces (}) instead of the given character and that too one character backwards of the given position (like the error in the write_string function). Also it doen't change the character background color given as argument.
void putChar(char character, short col, short row, char attr) {
unsigned char* vid_mem = (unsigned char *) VIDEO_MEM;
int offset = (row*80 + col)*2;
vid_mem += offset;
if(!attr) {
attr = 0x0f;
}
*vid_mem = (attr<<8)+character;
}
EDIT 2
My Boot Loader:
[org 0x7c00]
KERNEL equ 0x1000
mov [BOOT_DRIVE],dl
mov bp,0x9000
mov sp,bp
mov bx, msgReal
call print_string
call load_kernel
call switch_to_pm
jmp $
%include 'boot/bios.ASM'
%include 'boot/gdt.ASM'
%include 'boot/protected_mode.ASM'
%include 'boot/print32.ASM'
[bits 16]
load_kernel:
mov bx,msgKernel
call print_string
mov bx, KERNEL
mov dh, 15
mov dl, [BOOT_DRIVE]
call disk_load
ret
[bits 32]
BEGIN_PM:
mov ebx, msgProt
call print_string32
call KERNEL
jmp $
BOOT_DRIVE db 0
msgReal db "Booted in 16-bit mode",0
msgProt db "Successfully switched to 32-bit mode",0
msgKernel db "Loading the kernel onto memory",0
times 510-($-$$) db 0
dw 0xaa55
bios.ASM -
;BIOS Functions
[bits 16]
print_string:
pusha
mov cx,bx
mov ah,0x0e
printStringStart:
mov al,[bx]
cmp al,0
je done
int 0x10
inc bx
jmp printStringStart
done:
popa
ret
print_word:
pusha
mov ax,0x0000
mov cl,0x10
mov al,bh
div cl
call printDig
mov al,bh
and al,0x0f
call printDig
mov ax,0x0000
mov al,bl
div cl
call printDig
mov al,bl
and al,0x0f
call printDig
popa
ret
printDig:
cmp al,0x9
jg alpha
add al,'0'
mov ah,0x0e
int 0x10
jmp pDigDone
alpha:
sub al,0xa
add al,'A'
mov ah,0x0e
int 0x10
pDigDone:
ret
hex_prefix: db '0x',0
disk_load:
push dx
mov ah,0x02
mov al,dh
mov ch,0x00
mov dh,0x00
mov cl,0x02
int 0x13
jc disk_error
pop dx
cmp dh,al
jne disk_error
ret
disk_error:
mov ah,0x0e
mov al,'X'
int 0x10
mov bx,errMsg
call print_string
jmp $
errMsg:
db "Disk Read Error....."
times 80-20 db " "
db 0
gdt.ASM -
gdt_start:
gdt_null:
dd 0x0
dd 0x0
gdt_code:
dw 0xffff
dw 0x0
db 0x0
db 10011010b
db 11001111b
db 0x0
gdt_data:
dw 0xffff
dw 0x0
db 0x0
db 10010010b
db 11001111b
db 0x0
gdt_end:
gdt_descriptor:
dw gdt_end - gdt_start - 1
dd gdt_start
CODE_SEG equ gdt_code - gdt_start
DATA_SEG equ gdt_data - gdt_start
protected_mode.ASM -
[bits 16]
switch_to_pm:
cli
lgdt [gdt_descriptor]
mov eax, cr0
or eax, 0x1
mov cr0, eax
jmp CODE_SEG:init_pm
[bits 32]
init_pm:
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ebp,0x90000
mov esp,0x90000
call BEGIN_PM
print32.ASM -
[bits 32]
VIDEO_MEM equ 0xb8000
DEF_COLOR equ 0x0f
print_string32:
pusha
mov edx,VIDEO_MEM
print_string32_loop:
mov al, [ebx]
mov ah, DEF_COLOR
cmp al,0
je print_string32_end
mov [edx],ax
inc ebx
add edx,2
jmp print_string32_loop
print_string32_end:
popa
ret
I also add a kernel_start.asm file just before the kernel while linking to call the main function -
[bits 32]
[extern main]
call main
jmp $
And here's my make file -
C_SOURCES = $(wildcard drivers/*.c kernel/*.c)
HEADERS = $(wildcard kernel/*.h drivers/*.h)
OBJ = ${C_SOURCES:.c=.o}
all: os-image
os-image: boot/boot_sector.bin kernel.bin
cat $^ > $#
kernel.bin: kernel/kernel_start.o ${OBJ}
ld -o $# -Ttext 0x1000 $^ --oformat binary
%.o : %.c
gcc -std=c99 -Wall -pedantic -ffreestanding -c $< -o $#
%.o : %.asm
nasm $< -f elf64 -o $#
%.bin : %.asm
nasm $< -f bin -o $#
clean:
rm -fr kernel/*.o
rm -fr drivers/*.o
rm -fr boot/*.bin
rm -fr os-image *.bin *.o
With the changes suggested in other answer and comments, your problem doesn't seem to be reproducible for me. The following code works for me. I've tried to maintain how you coded it just so it makes sense to you:
#define VIDEO_MEM 0xb8000
void write_string( unsigned char colour, const char *string );
void write_string_line( unsigned char colour, const char *string, int pos );
void putChar(char character, short col, short row, unsigned char attr);
/* Place this at top of file as first code in kernel.o */
__asm__ ("call main\r\n" \
"cli\r\n" \
"hlt\r\n"
);
void main()
{
volatile unsigned char *vid = (unsigned char*) VIDEO_MEM;
int i=0;
for (i = 0; i < 2000; i++)
{
*vid = ' ';
*(vid+1) = 0x1f;
vid += 2;
}
write_string(0x1f,"The Kernel has been loaded successfully!!");
write_string_line(0x1f,"Testing Here!!",1);
putChar('Z',3,3,0xf3);
}
void write_string( unsigned char colour, const char *string ) {
volatile unsigned char *vid = (unsigned char*) VIDEO_MEM;
while(*string != 0)
{
*(vid) = *string;
*(vid+1) = colour;
++string;
vid+=2;
}
}
void write_string_line( unsigned char colour, const char *string, int pos ) {
volatile unsigned char *vid = (unsigned char*) VIDEO_MEM;
vid+=pos*160;
while(*string != 0)
{
*vid = *string;
*(vid+1) = colour;
++string;
vid+=2;
}
}
void putChar(char character, short col, short row, unsigned char attr) {
volatile unsigned char* vid_mem = (unsigned char *) VIDEO_MEM;
int offset = (row*80 + col)*2;
vid_mem += offset;
if(!attr) {
attr = 0x0f;
}
*(unsigned short int *)vid_mem = (attr<<8)+character;
/* This would do the same as line above
*vid_mem = character;
*(vid_mem+1) = attr;
*/
}
I've added the __asm__ at the beginning to make sure that code is the first to appear in the generated object file. It likely works without it. I've modified all your *vid pointers to be volatile . Since video is memory mapped IO you don't want to have the compiler potentially remove screen writes when it optimizes. Likely your code will work without volatile, but it is proper to add it here to avoid potential problems.
When run BOCHS this code produces this screen output:
If you use the code provided here and it doesn't work that would suggest the issue you are having is likely related to the a code you write in your bootloader that read the disk, enabled A20, set the GDT, entered protected mode, and then called into your C code. It is also possible problems could occur depending on how you compile and link your kernel.
Likely Cause of Undefined Behavior
After all the code and the make file were made available in EDIT 2 it became clear that one significant problem was that most of the code was compiled and linked to 64-bit objects and executables. That code won't work in 32-bit protected mode.
In the make file make these adjustments:
When compiling with GCC you need to add -m32 option
When assembling with GNU Assembler (as) targeting 32-bit objects you need to use --32
When linking with LD you need to add the -melf_i386 option
When assembling with NASM targeting 32-bit objects you need to change -f elf64 to -f elf32
A preferable option to using a 64-bit compiler and tool chain from the host environment is to create a cross compiler toolchain for i686 or i386.
This should work.
Each VGA cell is of 2 bytes long, First byte stores Character while the second byte stores the color.
Also make sure you make marked the pointer volatile. To avoid any type of unexpected changes(or optimizations) made by the compiler on that local field.
void write_string( int colour, const unsigned char *string )
{
volatile unsigned char *vid = (unsigned char*) VIDEO_MEM;
while( *string != 0 )
{
*vid++ = *string++;
*vid++ = colour;
}
}
You use *(vid) for first video character for color

Running Valgrind: False positives

I am trying to set up Valgrind to detect possible leaks from the native part of an app.
I have managed to build and get it running on my device, but I seem to be getting an error, causing many leaks to be detected whatever I use it on.
Here is the output of me using valgrind on 'ls' (that should come up with 0 leaks):
130|root#hwALE-H:/data/local/Inst/bin # ./valgrind ls
==16610== Memcheck, a memory error detector
==16610== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16610== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==16610== Command: ls
==16610==
WARNING: linker: /data/local/Inst/lib/valgrind/vgpreload_core-arm64-linux.so: unsupported flags DT_FLAGS_1=0x421
WARNING: linker: /data/local/Inst/lib/valgrind/vgpreload_memcheck-arm64-linux.so: unsupported flags DT_FLAGS_1=0x421
==16610== Invalid free() / delete / delete[] / realloc()
==16610== at 0x487D7D4: free (vg_replace_malloc.c:530)
==16610== by 0x40084FB: __dl__ZL12load_libraryilR10LinkedListI8LoadTask18TypeBasedAllocatorI15LinkedListEntryIS0_EEEPKciPK17android_dlextinfo (in /system/bin/linker64)
==16610== by 0x40097AF: __dl__ZL14find_librariesP6soinfoPKPKcmPS0_PNSt3__16vectorIS0_NS6_9allocatorIS0_EEEEmiPK17android_dlextinfo (in /system/bin/linker64)
==16610== by 0x400A883: __dl___linker_init (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== Address 0x4039150 is in a rw- anonymous segment
==16610==
==16610== Invalid free() / delete / delete[] / realloc()
==16610== at 0x487D7D4: free (vg_replace_malloc.c:530)
==16610== by 0x4009A43: __dl__ZL14find_librariesP6soinfoPKPKcmPS0_PNSt3__16vectorIS0_NS6_9allocatorIS0_EEEEmiPK17android_dlextinfo (in /system/bin/linker64)
==16610== by 0x400A883: __dl___linker_init (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== Address 0x403e010 is in a rw- anonymous segment
==16610==
callgrind_annotate
callgrind_control
cg_annotate
cg_diff
cg_merge
ms_print
valgrind
valgrind-di-server
valgrind-listener
vgdb
==16610==
==16610== HEAP SUMMARY:
==16610== in use at exit: 680 bytes in 12 blocks
==16610== total heap usage: 58 allocs, 48 frees, 72,870 bytes allocated
==16610==
==16610== LEAK SUMMARY:
==16610== definitely lost: 352 bytes in 7 blocks
==16610== indirectly lost: 0 bytes in 0 blocks
==16610== possibly lost: 16 bytes in 1 blocks
==16610== still reachable: 312 bytes in 4 blocks
==16610== suppressed: 0 bytes in 0 blocks
==16610== Rerun with --leak-check=full to see details of leaked memory
==16610==
==16610== For counts of detected and suppressed errors, rerun with: -v
==16610== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Any suggestions to help solve this issue will greatly appreciated!
EDIT: Here is the full logcat output from starting a "HelloJNI" type app, with a 6byte leak from native code. https://pastebin.com/j7TWC5Bu
The trace is hardly usable.

How do you test Node C++ add-ons with Valgrind?

Upon running valgrind node, Node seems to abort with a somewhat cryptic syscall-related error.
I'm on macOS Sierra, Node v8.2.1.
$ valgrind `which node` test-pass.js
==17115== Memcheck, a memory error detector
==17115== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==17115== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==17115== Command: /Users/junon/n/bin/node test-pass.js
==17115==
==17115== Syscall param msg->desc.port.name points to uninitialised byte(s)
==17115== at 0x10352B34A: mach_msg_trap (in /usr/lib/system/libsystem_kernel.dylib)
==17115== by 0x10352A796: mach_msg (in /usr/lib/system/libsystem_kernel.dylib)
==17115== by 0x103524485: task_set_special_port (in /usr/lib/system/libsystem_kernel.dylib)
==17115== by 0x1036C010E: _os_trace_create_debug_control_port (in /usr/lib/system/libsystem_trace.dylib)
==17115== by 0x1036C0458: _libtrace_init (in /usr/lib/system/libsystem_trace.dylib)
==17115== by 0x1029B29DF: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==17115== by 0x1021ECA1A: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==17115== by 0x1021ECC1D: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==17115== by 0x1021E84A9: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==17115== by 0x1021E8440: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==17115== by 0x1021E7523: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==17115== by 0x1021E75B8: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==17115== Address 0x7fff5fbfda8c is on thread 1's stack
==17115== in frame #2, created by task_set_special_port (???:)
==17115==
Assertion failed: (process_title.len + 1 == size), function uv_setup_args, file ../deps/uv/src/unix/proctitle.c, line 58.
==17115==
==17115== Process terminating with default action of signal 6 (SIGABRT)
==17115== at 0x103532D72: __pthread_sigmask (in /usr/lib/system/libsystem_kernel.dylib)
==17115== by 0x1034404A8: __abort (in /usr/lib/system/libsystem_c.dylib)
==17115== by 0x10344042E: abort (in /usr/lib/system/libsystem_c.dylib)
==17115== by 0x103407892: __assert_rtn (in /usr/lib/system/libsystem_c.dylib)
==17115== by 0x100BEC7B6: uv_setup_args (in /Users/junon/n/bin/node)
==17115== by 0x100A7EC9F: node::Start(int, char**) (in /Users/junon/n/bin/node)
==17115== by 0x100000E33: (below main) (in /Users/junon/n/bin/node)
==17115==
==17115== HEAP SUMMARY:
==17115== in use at exit: 71,518 bytes in 369 blocks
==17115== total heap usage: 469 allocs, 100 frees, 108,584 bytes allocated
==17115==
==17115== LEAK SUMMARY:
==17115== definitely lost: 0 bytes in 0 blocks
==17115== indirectly lost: 0 bytes in 0 blocks
==17115== possibly lost: 7,272 bytes in 115 blocks
==17115== still reachable: 10,270 bytes in 98 blocks
==17115== suppressed: 53,976 bytes in 156 blocks
==17115== Rerun with --leak-check=full to see details of leaked memory
==17115==
==17115== For counts of detected and suppressed errors, rerun with: -v
==17115== Use --track-origins=yes to see where uninitialised values come from
==17115== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1)
[1] 17115 abort valgrind `which node` test-pass.js
How are you supposed to check for memory leaks within C++ add-ons for Node.js? I see mentions of using node_g from around 2010, but that executable appears to be missing from my installation.

Valgrind errors in c++ threads

I am new to Valgrind. It throws 2 errors during memory check for the following code (http://en.cppreference.com/w/cpp/thread/lock_guard). Not sure how to interpret those errors.
#include <thread>
#include <mutex>
#include <iostream>
int g_i = 0;
std::mutex g_i_mutex; // protects g_i
void safe_increment()
{
std::lock_guard<std::mutex> lock(g_i_mutex);
++g_i;
std::cout << std::this_thread::get_id() << ": " << g_i << '\n';
}
int main()
{
std::cout << __func__ << ": " << g_i << '\n';
std::thread t1(safe_increment);
std::thread t2(safe_increment);
t1.join();
t2.join();
std::cout << __func__ << ": " << g_i << '\n';
}
I compiled this code on Mac using the following command:
clang++ simplethread.cpp -o simplethread -lpthread -std=c++11
The code runs as expected, but I get the following output from Valgrind.
$ valgrind --tool=memcheck ./simplethread
==34831== Memcheck, a memory error detector
==34831== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==34831== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==34831== Command: ./simplethread
==34831==
==34831== Syscall param msg->desc.port.name points to uninitialised byte(s)
==34831== at 0x10045F34A: mach_msg_trap (in /usr/lib/system/libsystem_kernel.dylib)
==34831== by 0x10045E796: mach_msg (in /usr/lib/system/libsystem_kernel.dylib)
==34831== by 0x100458485: task_set_special_port (in /usr/lib/system/libsystem_kernel.dylib)
==34831== by 0x1005F410E: _os_trace_create_debug_control_port (in /usr/lib/system/libsystem_trace.dylib)
==34831== by 0x1005F4458: _libtrace_init (in /usr/lib/system/libsystem_trace.dylib)
==34831== by 0x1000A99DF: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==34831== by 0x10001BA1A: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==34831== by 0x10001BC1D: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==34831== by 0x1000174A9: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==34831== by 0x100017440: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==34831== by 0x100016523: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==34831== by 0x1000165B8: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==34831== Address 0x10488ed4c is on thread 1's stack
==34831== in frame #2, created by task_set_special_port (???:)
==34831==
main: 0
==34831== Thread 2:
==34831== Invalid read of size 4
==34831== at 0x1005BC899: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==34831== by 0x1005BC886: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==34831== by 0x1005BC08C: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==34831== Address 0x18 is not stack'd, malloc'd or (recently) free'd
==34831==
==34831==
==34831== Process terminating with default action of signal 11 (SIGSEGV)
==34831== Access not within mapped region at address 0x18
==34831== at 0x1005BC899: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==34831== by 0x1005BC886: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==34831== by 0x1005BC08C: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==34831== If you believe this happened as a result of a stack
==34831== overflow in your program's main thread (unlikely but
==34831== possible), you can try to increase the size of the
==34831== main thread stack using the --main-stacksize= flag.
==34831== The main thread stack size used in this run was 8388608.
--34831:0:schedule VG_(sema_down): read returned -4
==34831==
==34831== HEAP SUMMARY:
==34831== in use at exit: 22,494 bytes in 168 blocks
==34831== total heap usage: 184 allocs, 16 frees, 28,638 bytes allocated
==34831==
==34831== LEAK SUMMARY:
==34831== definitely lost: 16 bytes in 1 blocks
==34831== indirectly lost: 56 bytes in 2 blocks
==34831== possibly lost: 72 bytes in 3 blocks
==34831== still reachable: 4,368 bytes in 10 blocks
==34831== suppressed: 17,982 bytes in 152 blocks
==34831== Rerun with --leak-check=full to see details of leaked memory
==34831==
==34831== For counts of detected and suppressed errors, rerun with: -v
==34831== Use --track-origins=yes to see where uninitialised values come from
==34831== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 1 from 1)
Segmentation fault: 11
What does these errors mean ?

Resources