JeMalloc does not create memory leak dump - c++11

I need help with memory profiling using JeMalloc.
I do the following things:
git clone https://github.com/jemalloc/jemalloc
cd jemalloc
./autogen.sh --enable-perf
make dist
make
sudo make install
export MALLOC_CONF=prof_leak:true,lg_prof_sample:0,prof_final:true
export LD_PRELOAD=/usr/local/Cellar/jemalloc/5.1.0/lib/libjemalloc.dylib
Then I run my application:
./some_executed_file
It is 100% that this binary file will use jemalloc
Because when I call
typedef struct {
char *cur;
char *end;
} MallocStatus;
static void GetJemallocStatus(void *mstat_arg, const char *status) {
MallocStatus *mstat = reinterpret_cast<MallocStatus *>(mstat_arg);
size_t status_len = status ? strlen(status) : 0;
size_t buf_size = (size_t)(mstat->end - mstat->cur);
if (!status_len || status_len > buf_size) {
return;
}
snprintf(mstat->cur, buf_size, "%s", status);
mstat->cur += status_len;
}
MallocStatus mstat;
const unsigned int kMallocStatusLen = 1000000;
std::unique_ptr<char[]> buf{new char[kMallocStatusLen + 1]};
mstat.cur = buf.get();
mstat.end = buf.get() + kMallocStatusLen;
je_malloc_stats_print(GetJemallocStatus, &mstat, "");
stats->append(buf.get());
I see JeMalloc statistics.
Regarding to
https://github.com/jemalloc/jemalloc/wiki/Use-Case:-Leak-Checking
I do everything correct - but I still don't see jeprof dump file do analyze memory leaks.
Thanks in advance.

Try adding prof:true,prof_active:true to your MALLOC_CONF, and using --enable-prof flag instead of --enable-perf.

Related

Linux kernel_write function returns EFBIG when appending data to big file

The task is to write simple character device that copies all the data written to the device to tmp a file.
I use kernel_write function to write data to file and its work fine most of the cases. But when the output file size is bigger than 2.1 GB, kernel_write function fails with return value -27.
To write to file I use this function:
void writeToFile(void* buf, size_t size, loff_t *offset) {
struct file* destFile;
char* filePath = "/tmp/output";
destFile = filp_open(filePath, O_CREAT|O_WRONLY|O_APPEND, 0666);
if (IS_ERR(destFile) || destFile == NULL) {
printk("Cannot open destination file");
return;
}
size_t res = kernel_write(destFile, buf, size, offset);
printk("%ld", res);
filp_close(destFile, NULL);
}
If the size of "/tmp/output" < 2.1 GB, this function works just fine.
If the size of "/tmp/output"> 2.1 GB, kernel_write starts to return -27.
How can I fix this?
Thanks
You need to enable Large File Support (LFS) with the O_LARGEFILE flag.
The below code worked for me. Sorry, I made some other changes for debugging, but I commented above the relevant line.
struct file* writeToFile(void* buf, size_t size, loff_t *offset)
{
struct file* destFile;
char* filePath = "/tmp/output";
size_t res;
// Add the O_LARGEFILE flag here
destFile = filp_open(filePath, O_CREAT | O_WRONLY | O_APPEND | O_LARGEFILE, 0666);
if (IS_ERR(destFile))
{
printk("Error in opening: <%ld>", (long)destFile);
return destFile;
}
if (destFile == NULL)
{
printk("Error in opening: null");
return destFile;
}
res = kernel_write(destFile, buf, size, offset);
printk("CODE: <%ld>", res);
filp_close(destFile, NULL);
return destFile;
}
To test it, I created a file with fallocate -l 3G /tmp/output, then removed the O_CREAT flag because it was giving the kernel permission errors.
I should add a disclaimer that a lot of folks says that File I/O from the kernel is a bad idea. Even while testing this out on my own, I accidentally crashed my computer twice due to dumb errors.
Maybe do this instead: Read/Write from /proc File

Missing header <fluent-bit.h> while compiling C program

I'm trying to compile my C program using library Api of fluent-bit , but the header fluent-bit.h is missing and I don't understand why.
I installed fluent-bit using installation guide
Here is my code I want to test:
#include <fluent-bit.h>
int main()
{
int i;
int n;
char tmp[256];
flb_ctx_t *ctx;
int in_ffd;
int out_ffd;
/* Initialize library */
ctx = flb_create();
if (!ctx) {
exit(EXIT_FAILURE);
}
in_ffd = flb_input(ctx, "lib", NULL);
flb_input_set(ctx, in_ffd, "tag", "test", NULL);
out_ffd = flb_output(ctx, "stdout", NULL);
flb_output_set(ctx, out_ffd, "match", "test", NULL);
/* Start the background worker */
flb_start(ctx);
/* Push some data */
for (i = 0; i < 100; i++) {
n = snprintf(tmp, sizeof(tmp) - 1,
"[%f, {\"key\": \"val %i\"}]",
flb_time_now(), i);
flb_lib_push(ctx, in_ffd, tmp, n);
}
flb_stop(ctx);
/* Release Resources */
flb_destroy(ctx);
return 0;
}
Here the error I got:
hello.c:1:24: fatal error: fluent-bit.h: No such file or directory
#include <fluent-bit.h>
^
compilation terminated.
Problem solved, I didn't install fluent-bit and headers properly.
Here was the problem : the headers were missing, so move on to cd /path/to/downloaded/fluent-bit-x.y.z/includes
Then use
sudo cmake .
sudo make install
You'll get an output saying that the headers had been installed on your system.
To make sure fluent-bit is correctly installed too :
cd ..
sudo cmake .
sudo make install
You can now use the fluent-bit API without problems

How can I use simd in MIPS?

I have installed mipsel-linux-gcc in the pictrue
Now I have a file simd.c
#include<stdio.h>
#include"simdType.h"
int main()
{
v4i32 m,t;
v4f32 a,b,c,s;
a=b+c;
t=b<c;
s = __builtin_shuffle(b,c,m);
return 0;
}
then I run this command:
mipsel-linux-gcc -S simd.c -mfp64 -Wa,-mmsa -mhard-float
then I get simd.s, but it's not in simd format.
Who can help me ? Thanks!

Ruby Gems C extension example not working

I am trying to follow this tutorial on building c extension in ruby gems http://guides.rubygems.org/gems-with-extensions/.
I have the following files:
ext/my_malloc/extconf.rb
require "mkmf"
abort "missing malloc()" unless have_func "malloc"
abort "missing free()" unless have_func "free"
create_makefile "my_malloc/my_malloc"
ext/my_malloc/my_malloc.c
#include <ruby.h>
struct my_malloc {
size_t size;
void *ptr;
};
static void
my_malloc_free(void *p) {
struct my_malloc *ptr = p;
if (ptr->size > 0)
free(ptr->ptr);
}
static VALUE
my_malloc_alloc(VALUE klass) {
VALUE obj;
struct my_malloc *ptr;
obj = Data_Make_Struct(klass, struct my_malloc, NULL, my_malloc_free, ptr);
ptr->size = 0;
ptr->ptr = NULL;
return obj;
}
static VALUE
my_malloc_init(VALUE self, VALUE size) {
struct my_malloc *ptr;
size_t requested = NUM2SIZET(size);
if (0 == requested)
rb_raise(rb_eArgError, "unable to allocate 0 bytes");
Data_Get_Struct(self, struct my_malloc, ptr);
ptr->ptr = malloc(requested);
if (NULL == ptr->ptr)
rb_raise(rb_eNoMemError, "unable to allocate %ld bytes", requested);
ptr->size = requested;
return self;
}
static VALUE
my_malloc_release(VALUE self) {
struct my_malloc *ptr;
Data_Get_Struct(self, struct my_malloc, ptr);
if (0 == ptr->size)
return self;
ptr->size = 0;
free(ptr->ptr);
return self;
}
void
Init_my_malloc(void) {
VALUE cMyMalloc;
cMyMalloc = rb_const_get(rb_cObject, rb_intern("MyMalloc"));
rb_define_alloc_func(cMyMalloc, my_malloc_alloc);
rb_define_method(cMyMalloc, "initialize", my_malloc_init, 1);
rb_define_method(cMyMalloc, "free", my_malloc_release, 0);
}
I do the following to build the extension:
$ cd ext/my_malloc
$ ruby extconf.rb
checking for malloc()... yes
checking for free()... yes
creating Makefile
$ make
compiling my_malloc.c
linking shared-object my_malloc.bundle
$ cd ../..
$ ruby -Ilib:ext -r my_malloc -e "p MyMalloc.new(5).free"
However, I get the following error on the last command:
/Users/Daniel/.rbenv/versions/2.1.6/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- my_malloc (LoadError)
from
/Users/Daniel/.rbenv/versions/2.1.6/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
Note, I'm using rbenv, I've tried running rbenv rehash and I'm running version 2.1.6.
The correct shell command is:
ruby -Iext/my_malloc -r my_malloc -e "p MyMalloc.new(5).free"
The code also has some other mistakes. Correct
rb_raise(rb_eNoMemError, "unable to allocate %ld bytes", requested);
to
rb_raise(rb_eNoMemError, "unable to allocate %" PRIuSIZE " bytes", requested);
since requested has type size_t and not long (PRIuSIZE is non-standard and defined in "ruby/ruby.h"). And
cMyMalloc = rb_const_get(rb_cObject, rb_intern("MyMalloc"));
to
cMyMalloc = rb_define_class("MyMalloc", rb_cObject);
to actually define the MyMalloc class.

It really looks like OS X has a bug when using poll() on a named pipe (FIFO)... can an expert confirm?

I'm been trying to poll from a set of named-pipes for a little while now and i keep getting an immediate response of POLLNVAL on any named pipe file descriptor. After finding this blog post about broken polling in OS X I'm pretty certain that this is a b-u-g bug in OS X.
I'm already planning on switching my code to using UDP sockets, but i wanted to ask SO for verification about this a) so that I'm sure it's really broken, and b) for documentation purposes.
Here is a stripped down version of the code I wrote (although the code in the link above, which I tested, spells it out pretty well):
#includes
...
....
#
static const char* first_fifo_path = "/tmp/fifo1";
static const char* second_fifo_path = "/tmp/fifo2";
int setup_read_fifo(const char* path){
int fifo_fd = -1;
if( mkfifo(path, S_IRWXU | S_IRWXG | S_IRWXO) )
perror("error calling mkfifo()... already exists?\n");
if((fifo_fd = open(path, O_RDONLY | O_NDELAY)) < 0)
perror("error calling open()");
return fifo_fd;
}
void do_poll(int fd1, int fd2){
char inbuf[1024];
int num_fds = 2;
struct pollfd fds[num_fds];
int timeout_msecs = 500;
fds[0].fd = fd1;
fds[1].fd = fd2;
fds[0].events = POLLIN;
fds[1].events = POLLIN;
int ret;
while((ret = poll(fds, num_fds, timeout_msecs)) >= 0){
if(ret < 0){
printf("Error occured when polling\n");
printf("ret %d, errno %d\n", ret, errno);
printf("revents = %xh : %xh \n\n", fds[0].revents, fds[1].revents);
}
if(ret == 0){
printf("Timeout Occurred\n");
continue;
}
for(int i = 0; i< num_fds; i++){
if(int event = fds[i].revents){
if(event & POLLHUP)
printf("Pollhup\n");
if(event & POLLERR)
printf("POLLERR\n");
if(event & POLLNVAL)
printf("POLLNVAL\n");
if(event & POLLIN){
read(fds[i].fd, inbuf, sizeof(inbuf));
printf("Received: %s", inbuf);
}
}
}
}
}
int main (int argc, char * const argv[]) {
do_poll(setup_read_fifo(first_fifo_path), setup_read_fifo(second_fifo_path));
return 0;
}
this outputs:
$ ./executive
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
POLLNVAL
...
ad nauseam.
Anybody else run into this? This is a real bug right?
This seems to be a genuine bug. It works as expected on Linux and OpenBSD and fails as you describe on OS X.
OSX 10.4.1, I can confirm the behaviour. The same code works fine (as long as timeout messages are fine) on Linux. All the evidence, including this - http://www.virtualbox.de/changeset/12347 - suggests that there is a real problem.
Yup, known bug. I think the poll breakage is only since 10.4, we had to deal with it in Fink. Glib's configure.in has a test for this, so you can be sure that you're not imagining it. (Well, not precisely this, glib tests for poll on devices, not fifos.)

Resources