So I've got a very basic example of talking to a facebook server over https, but valgrind is complaining sadly. So I assume I'm not setting something up incorrectly... does anyone know what I'm doing wrong?
Here's my code:
#include <string>
#include <iostream>
#include <curl/curl.h>
size_t write_fn_impl( void* ptr, size_t size, size_t nmemb, void * data )
{
std::string * result = static_cast<std::string*>(data);
*result += std::string( (char*)ptr, size*nmemb );
return size*nmemb;
}
int main()
{
std::string url_full="https://graph.facebook.com/me";
std::string useragent = "Facebook API C++ Client (curl)";
CURL * ch_ = curl_easy_init();
char error_buffer[CURL_ERROR_SIZE];
curl_easy_setopt( ch_, CURLOPT_ERRORBUFFER, error_buffer );
curl_easy_setopt( ch_, CURLOPT_WRITEFUNCTION, &write_fn_impl );
std::string result;
curl_easy_setopt( ch_, CURLOPT_WRITEDATA, &result );
int id = 1;
curl_easy_setopt( ch_, CURLOPT_VERBOSE, id );
curl_easy_setopt( ch_, CURLOPT_URL, url_full.c_str() );
curl_easy_setopt( ch_, CURLOPT_USERAGENT, useragent.c_str() );
curl_easy_setopt( ch_, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt( ch_, CURLOPT_TIMEOUT, 30);
curl_easy_perform(ch_);
curl_easy_cleanup(ch_);
std::cout<< result<<std::endl;
}
And what valgrind says is:
==14149== Memcheck, a memory error detector
==14149== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==14149== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==14149== Command: ./a.out
==14149==
* About to connect() to graph.facebook.com port 443 (#0)
* Trying 66.220.146.47... * connected
* Connected to graph.facebook.com (66.220.146.47) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
==14149== Syscall param write(buf) points to uninitialised byte(s)
==14149== at 0x4268113: __write_nocancel (in /lib/tls/i686/cmov/libc-2.10.1.so)
==14149== by 0x44A5A8E: BIO_write (in /lib/i686/cmov/libcrypto.so.0.9.8)
==14149== by 0x43E49B8: ssl23_write_bytes (in /lib/i686/cmov/libssl.so.0.9.8)
==14149== by 0x43E39AB: ssl23_connect (in /lib/i686/cmov/libssl.so.0.9.8)
==14149== by 0x43F0D49: SSL_connect (in /lib/i686/cmov/libssl.so.0.9.8)
==14149== by 0x4050EB0: ossl_connect_common (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x4052202: Curl_ossl_connect (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x406597F: Curl_ssl_connect (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x403FF1B: Curl_http_connect (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x4046F6D: Curl_protocol_connect (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x404C396: Curl_connect (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x4059B23: Curl_perform (in /usr/lib/libcurl.so.4.1.1)
==14149== Address 0x47e92df is 15 bytes inside a block of size 21,848 alloc'd
==14149== at 0x4024C1C: malloc (vg_replace_malloc.c:195)
==14149== by 0x4446EFD: ??? (in /lib/i686/cmov/libcrypto.so.0.9.8)
==14149== by 0x444755B: CRYPTO_malloc (in /lib/i686/cmov/libcrypto.so.0.9.8)
==14149== by 0x44A4EF7: BUF_MEM_grow (in /lib/i686/cmov/libcrypto.so.0.9.8)
==14149== by 0x43E3BAB: ssl23_connect (in /lib/i686/cmov/libssl.so.0.9.8)
==14149== by 0x43F0D49: SSL_connect (in /lib/i686/cmov/libssl.so.0.9.8)
==14149== by 0x4050EB0: ossl_connect_common (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x4052202: Curl_ossl_connect (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x406597F: Curl_ssl_connect (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x403FF1B: Curl_http_connect (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x4046F6D: Curl_protocol_connect (in /usr/lib/libcurl.so.4.1.1)
==14149== by 0x404C396: Curl_connect (in /usr/lib/libcurl.so.4.1.1)
And pages more....
MK is partially correct. Valgrind does throw up a lot of junk warnings about OpenSSL. But in my case the crashes I was seeing did seem to be due to some trouble with how I was using openSSL. In particular it was not getting correctly set up for multithreaded use. The curl docs cover what you need to do .. but somehow I must have missed it)
Anyway heres the suppression file that helped me find it .. it may be of use to someone.. But beware it probably doesnt' catch everything you'd want to catch, and it probably catches some things you dont want...
{
openssl-rand-write
Memcheck:Param
write(buf)
fun:__write_nocancel
fun:BIO_write
fun:ssl23_write_bytes
fun:ssl23_connect
fun:SSL_connect
fun:ossl_connect_common
}
{
openssl-rand-write2
Memcheck:Param
write(buf)
fun:__write_nocancel
fun:BIO_write
fun:ssl3_write_pending
obj:/lib/i686/cmov/libssl.so.0.9.8
fun:ssl3_write_bytes
fun:ssl3_write
fun:SSL_write
}
{
openssl-rand-write3
Memcheck:Param
write(buf)
fun:__write_nocancel
fun:BIO_write
...
fun:ossl_connect_common
}
{
openssl-rand-uninit_mod_inverse
Memcheck:Cond
fun:BN_mod_inverse
...
obj:/lib/i686/cmov/libcrypto.so.0.9.8
}
{
openssl-rand-uninit_div
Memcheck:Cond
fun:BN_div
...
obj:/lib/i686/cmov/libcrypto.so.0.9.8
}
{
openssl-uninit-padding
Memcheck:Cond
fun:RSA_padding_add_PKCS1_type_2
obj:/lib/i686/cmov/libcrypto.so.0.9.8
}
{
openssl-uninit-ucmp
Memcheck:Cond
fun:BN_ucmp
obj:/lib/i686/cmov/libcrypto.so.0.9.8
}
{
openssl-uninit-encrypt
Memcheck:Cond
obj:/lib/i686/cmov/libcrypto.so.0.9.8
fun:RSA_public_encrypt
}
{
openssl-uninit-ssl3_read_bytes
Memcheck:Cond
fun:ssl3_read_bytes
fun:ssl3_read
fun:SSL_read
}
{
openssl-uninit-get_finished
Memcheck:Cond
fun:ssl3_get_finished
fun:ssl3_connect
fun:SSL_connect
fun:ossl_connect_common
}
{
openssl-uninit-read_bytes
Memcheck:Cond
...
fun:ossl_connect_common
}
{
openssl-value4-connect_common
Memcheck:Value4
...
fun:ossl_connect_common
}
{
openssl-uninit-encrypt
Memcheck:Cond
...
fun:RSA_public_encrypt
}
Last time somebody tried to make sure OpenSSL runs clean under valgrind Bad Things (tm) happened:
http://blogs.fsfe.org/tonnerre/archives/24
So I would just ignore any vlagrind warnings about OpenSSL.
Related
This is my first experience with Cairo. I create the surface using this function:
//This function should give us a new x11 surface to draw on.
cairo_surface_t *create_x11_surface(Display *d, int *x, int *y) {
Drawable da;
int screen;
cairo_surface_t *sfc;
Screen *scr;
screen = DefaultScreen(d);
scr = DefaultScreenOfDisplay(d);
if (!*x || !*y) {
*x = WidthOfScreen(scr) / 2;
*y = HeightOfScreen(scr) / 2;
da =
XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, *x, *y, 0, 0, 0);
} else
da =
XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, *x, *y, 0, 0, 0);
XSelectInput(d, da, ButtonPressMask | ButtonReleaseMask | KeyPressMask |
ButtonMotionMask | StructureNotifyMask);
// http://www.lemoda.net/c/xlib-wmclose/index.html
/* "wm_delete_window" is the Atom which corresponds to the delete
window message sent by the window manager. */
Atom wm_delete_window;
wm_delete_window = XInternAtom(d, "WM_DELETE_WINDOW", False);
/* Set up the window manager protocols. The third argument here is
meant to be an array, and the fourth argument is the size of
the array. */
XSetWMProtocols(d, da, &wm_delete_window, 1);
XMapWindow(d, da);
sfc = cairo_xlib_surface_create(d, da, DefaultVisual(d, screen), *x, *y);
return sfc;
}
My main() consists of creating a Drawer object and calling its run method. Drawer is defined as follows (slightly simplified, the unused template parameter is not shown):
struct Drawer {
Drawer() {
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Failed to open display\n");
exit(-1);
}
// create a new cairo surface in an x11 window as well as a cairo_t* to
// draw on the x11 window with.
int x=500, y=500;
surface = create_x11_surface(d, &x, &y);
cr = cairo_create(surface);
}
// https://stackoverflow.com/a/19308254/2725810
~Drawer() {
cairo_destroy(cr);
cairo_surface_destroy(surface);
XCloseDisplay(d);
}
// Returns true if need to continue or false if quiting
bool processEvents() {
XEvent e;
if (XPending(cairo_xlib_surface_get_display(surface))) {
XNextEvent(cairo_xlib_surface_get_display(surface), &e);
switch (e.type) {
case ButtonPress:
drag_start_x = e.xbutton.x;
drag_start_y = e.xbutton.y;
break;
case ButtonRelease:
last_delta_x = 0;
last_delta_y = 0;
break;
case MotionNotify:
// http://cairographics.org/manual/cairo-Transformations.html#cairo-translate
cairo_translate(cr, e.xmotion.x - drag_start_x - last_delta_x,
e.xmotion.y - drag_start_y - last_delta_y);
last_delta_x = e.xmotion.x - drag_start_x;
last_delta_y = e.xmotion.y - drag_start_y;
break;
case ConfigureNotify:
cairo_xlib_surface_set_size(surface, e.xconfigure.width,
e.xconfigure.height);
break;
case ClientMessage:
return false;
default:
fprintf(stderr, "Dropping unhandled XEevent.type = %d.\n",
e.type);
}
}
return true;
}
void draw() {
cairo_push_group(cr);
// Clear the background
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_paint(cr);
cairo_set_source_rgb(cr, 0, 1, 0);
cairo_move_to(cr, 0, 0);
cairo_line_to(cr, 256, 256);
cairo_move_to(cr, 256, 0);
cairo_line_to(cr, 0, 256);
cairo_set_line_width(cr, 10.0);
cairo_stroke(cr);
cairo_pop_group_to_source(cr);
cairo_paint(cr);
cairo_surface_flush(surface);
XFlush(d);
}
void run() {
while (1) {
if (!processEvents()) break;
draw();
sleep(0.1);
}
}
private:
Display *d;
cairo_surface_t* surface;
cairo_t* cr;
int last_delta_x = 0, last_delta_y = 0;
int drag_start_x, drag_start_y;
};
The program is compiled with gcc version 4.8.2.
valgrind reports memory leaks and points to calls to cairo_stroke and other Cairo functions as the leak causes. It also says that some memory remains not freed when the program finishes despite the fact that Drawer's destructor gets called. Here is the output of valgrind:
==6897== Memcheck, a memory error detector
==6897== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==6897== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==6897== Command: ./Test
==6897==
Dropping unhandled XEevent.type = 21.
Dropping unhandled XEevent.type = 19.
Dropping unhandled XEevent.type = 65.
==6897==
==6897== HEAP SUMMARY:
==6897== in use at exit: 12,696 bytes in 12 blocks
==6897== total heap usage: 19,039 allocs, 19,027 frees, 8,088,426 bytes allocated
==6897==
==6897== 72 bytes in 1 blocks are still reachable in loss record 1 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x4E59F7C: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5B5B9: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5BAE5: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5CAB0: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5D87D: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4EA2050: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4EA3142: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5FECF: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E57F01: cairo_push_group_with_content (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x40590D: Drawer<NoGraph<StateNeighbor<Pancake, true> > >::draw() (Drawer.h:115)
==6897== by 0x403A7A: Drawer<NoGraph<StateNeighbor<Pancake, true> > >::run() (Drawer.h:138)
==6897==
==6897== 72 bytes in 1 blocks are still reachable in loss record 2 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x4E59F7C: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5B5B9: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5BAE5: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5CDB2: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4EB4DE3: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5DA63: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4ECEA3C: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4EA2411: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E651E1: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5F168: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E58994: cairo_stroke (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897==
==6897== 160 bytes in 1 blocks are still reachable in loss record 3 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x4E850BC: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E851BC: cairo_pattern_create_rgba (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E6028A: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E57FC9: cairo_set_source_rgb (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x405959: Drawer<NoGraph<StateNeighbor<Pancake, true> > >::draw() (Drawer.h:121)
==6897== by 0x403A7A: Drawer<NoGraph<StateNeighbor<Pancake, true> > >::run() (Drawer.h:138)
==6897== by 0x402269: main (Test.cpp:48)
==6897==
==6897== 256 bytes in 2 blocks are still reachable in loss record 4 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x4E8529A: cairo_pattern_create_for_surface (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5FD7F: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E57F48: cairo_pop_group (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5809D: cairo_pop_group_to_source (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x405A38: Drawer<NoGraph<StateNeighbor<Pancake, true> > >::draw() (Drawer.h:129)
==6897== by 0x403A7A: Drawer<NoGraph<StateNeighbor<Pancake, true> > >::run() (Drawer.h:138)
==6897== by 0x402269: main (Test.cpp:48)
==6897==
==6897== 352 bytes in 1 blocks are definitely lost in loss record 5 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x4ECC831: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4ECC933: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4ECD497: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4EB3922: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4EB4E32: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5DA63: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4ECEA3C: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4EA2411: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E651E1: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E5F168: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x4E58994: cairo_stroke (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897==
==6897== 1,424 bytes in 1 blocks are still reachable in loss record 6 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x4E604E7: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==6897== by 0x403A04: Drawer<NoGraph<StateNeighbor<Pancake, true> > >::Drawer(NoGraph<StateNeighbor<Pancake, true> > const&) (Drawer.h:66)
==6897== by 0x40225D: main (Test.cpp:47)
==6897==
==6897== 2,072 bytes in 1 blocks are still reachable in loss record 7 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5FCBACE: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5FCD585: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x4010139: call_init.part.0 (dl-init.c:78)
==6897== by 0x4010222: _dl_init (dl-init.c:36)
==6897== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==6897==
==6897== 2,072 bytes in 1 blocks are still reachable in loss record 8 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5FCA61F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5FCD5A0: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x4010139: call_init.part.0 (dl-init.c:78)
==6897== by 0x4010222: _dl_init (dl-init.c:36)
==6897== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==6897==
==6897== 2,072 bytes in 1 blocks are still reachable in loss record 9 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5FE5A8F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5FBC1A5: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5FCD5AB: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x4010139: call_init.part.0 (dl-init.c:78)
==6897== by 0x4010222: _dl_init (dl-init.c:36)
==6897== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==6897==
==6897== 2,072 bytes in 1 blocks are still reachable in loss record 10 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x60053CF: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5FCD5AB: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x4010139: call_init.part.0 (dl-init.c:78)
==6897== by 0x4010222: _dl_init (dl-init.c:36)
==6897== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==6897==
==6897== 2,072 bytes in 1 blocks are still reachable in loss record 11 of 11
==6897== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6897== by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5FCFCBF: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==6897== by 0x4010139: call_init.part.0 (dl-init.c:78)
==6897== by 0x4010222: _dl_init (dl-init.c:36)
==6897== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==6897==
==6897== LEAK SUMMARY:
==6897== definitely lost: 352 bytes in 1 blocks
==6897== indirectly lost: 0 bytes in 0 blocks
==6897== possibly lost: 0 bytes in 0 blocks
==6897== still reachable: 12,344 bytes in 11 blocks
==6897== suppressed: 0 bytes in 0 blocks
==6897==
==6897== For counts of detected and suppressed errors, rerun with: -v
==6897== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
What am I not doing right?
UPDATE: After inserting a call to cairo_debug_reset_static_data() from the destructor as suggested here, the output of valgrind became somewhat shorter:
==7310== Memcheck, a memory error detector
==7310== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7310== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==7310== Command: ./Test
==7310==
Dropping unhandled XEevent.type = 21.
Dropping unhandled XEevent.type = 19.
Dropping unhandled XEevent.type = 65.
==7310==
==7310== HEAP SUMMARY:
==7310== in use at exit: 10,712 bytes in 6 blocks
==7310== total heap usage: 29,352 allocs, 29,346 frees, 12,459,938 bytes allocated
==7310==
==7310== 352 bytes in 1 blocks are definitely lost in loss record 1 of 6
==7310== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7310== by 0x4ECC831: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310== by 0x4ECC933: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310== by 0x4ECD497: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310== by 0x4EB3922: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310== by 0x4EB4E32: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310== by 0x4E5DA63: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310== by 0x4ECEA3C: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310== by 0x4EA2411: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310== by 0x4E651E1: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310== by 0x4E5F168: ??? (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310== by 0x4E58994: cairo_stroke (in /usr/lib/x86_64-linux-gnu/libcairo.so.2.11301.0)
==7310==
==7310== 2,072 bytes in 1 blocks are still reachable in loss record 2 of 6
==7310== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7310== by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5FCBACE: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5FCD585: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x4010139: call_init.part.0 (dl-init.c:78)
==7310== by 0x4010222: _dl_init (dl-init.c:36)
==7310== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==7310==
==7310== 2,072 bytes in 1 blocks are still reachable in loss record 3 of 6
==7310== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7310== by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5FCA61F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5FCD5A0: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x4010139: call_init.part.0 (dl-init.c:78)
==7310== by 0x4010222: _dl_init (dl-init.c:36)
==7310== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==7310==
==7310== 2,072 bytes in 1 blocks are still reachable in loss record 4 of 6
==7310== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7310== by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5FE5A8F: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5FBC1A5: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5FCD5AB: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x4010139: call_init.part.0 (dl-init.c:78)
==7310== by 0x4010222: _dl_init (dl-init.c:36)
==7310== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==7310==
==7310== 2,072 bytes in 1 blocks are still reachable in loss record 5 of 6
==7310== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7310== by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x60053CF: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5FCD5AB: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x4010139: call_init.part.0 (dl-init.c:78)
==7310== by 0x4010222: _dl_init (dl-init.c:36)
==7310== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==7310==
==7310== 2,072 bytes in 1 blocks are still reachable in loss record 6 of 6
==7310== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7310== by 0x5FCCE9A: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5FCFCBF: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x5F7F508: ??? (in /usr/lib/x86_64-linux-gnu/libpixman-1.so.0.30.2)
==7310== by 0x4010139: call_init.part.0 (dl-init.c:78)
==7310== by 0x4010222: _dl_init (dl-init.c:36)
==7310== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==7310==
==7310== LEAK SUMMARY:
==7310== definitely lost: 352 bytes in 1 blocks
==7310== indirectly lost: 0 bytes in 0 blocks
==7310== possibly lost: 0 bytes in 0 blocks
==7310== still reachable: 10,360 bytes in 5 blocks
==7310== suppressed: 0 bytes in 0 blocks
==7310==
==7310== For counts of detected and suppressed errors, rerun with: -v
==7310== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
BTW, why doesn't valgrind show the full callstack for the lost record and stops at cairo_stroke instead? My program is compiled with gcc with the -g flag...
UPDATE: As requested in the comments, here is the whole working example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <cairo-xlib.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <unistd.h>
//This function should give us a new x11 surface to draw on.
cairo_surface_t *create_x11_surface(Display *d, int *x, int *y) {
Drawable da;
int screen;
cairo_surface_t *sfc;
Screen *scr;
screen = DefaultScreen(d);
scr = DefaultScreenOfDisplay(d);
if (!*x || !*y) {
*x = WidthOfScreen(scr) / 2;
*y = HeightOfScreen(scr) / 2;
da =
XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, *x, *y, 0, 0, 0);
} else
da =
XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, *x, *y, 0, 0, 0);
XSelectInput(d, da, ButtonPressMask | ButtonReleaseMask | KeyPressMask |
ButtonMotionMask | StructureNotifyMask);
// http://www.lemoda.net/c/xlib-wmclose/index.html
/* "wm_delete_window" is the Atom which corresponds to the delete
window message sent by the window manager. */
Atom wm_delete_window;
wm_delete_window = XInternAtom(d, "WM_DELETE_WINDOW", False);
/* Set up the window manager protocols. The third argument here is
meant to be an array, and the fourth argument is the size of
the array. */
XSetWMProtocols(d, da, &wm_delete_window, 1);
XMapWindow(d, da);
sfc = cairo_xlib_surface_create(d, da, DefaultVisual(d, screen), *x, *y);
return sfc;
}
struct Drawer {
Drawer() {
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Failed to open display\n");
exit(-1);
}
// create a new cairo surface in an x11 window as well as a cairo_t* to
// draw on the x11 window with.
int x=500, y=500;
surface = create_x11_surface(d, &x, &y);
cr = cairo_create(surface);
}
// https://stackoverflow.com/a/19308254/2725810
~Drawer() {
cairo_destroy(cr);
cairo_surface_destroy(surface);
XCloseDisplay(d);
}
// Returns true if need to continue or false if quiting
bool processEvents() {
XEvent e;
if (XPending(cairo_xlib_surface_get_display(surface))) {
XNextEvent(cairo_xlib_surface_get_display(surface), &e);
switch (e.type) {
case ButtonPress:
drag_start_x = e.xbutton.x;
drag_start_y = e.xbutton.y;
break;
case ButtonRelease:
last_delta_x = 0;
last_delta_y = 0;
break;
case MotionNotify:
// http://cairographics.org/manual/cairo-Transformations.html#cairo-translate
cairo_translate(cr, e.xmotion.x - drag_start_x - last_delta_x,
e.xmotion.y - drag_start_y - last_delta_y);
last_delta_x = e.xmotion.x - drag_start_x;
last_delta_y = e.xmotion.y - drag_start_y;
break;
case ConfigureNotify:
cairo_xlib_surface_set_size(surface, e.xconfigure.width,
e.xconfigure.height);
break;
case ClientMessage:
return false;
default:
fprintf(stderr, "Dropping unhandled XEevent.type = %d.\n",
e.type);
}
}
return true;
}
void draw() {
cairo_push_group(cr);
// Clear the background
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_paint(cr);
cairo_set_source_rgb(cr, 0, 1, 0);
cairo_move_to(cr, 0, 0);
cairo_line_to(cr, 256, 256);
cairo_move_to(cr, 256, 0);
cairo_line_to(cr, 0, 256);
cairo_set_line_width(cr, 10.0);
cairo_stroke(cr);
cairo_pop_group_to_source(cr);
cairo_paint(cr);
cairo_surface_flush(surface);
XFlush(d);
}
void run() {
while (1) {
if (!processEvents()) break;
draw();
sleep(0.1);
}
}
private:
Display *d;
cairo_surface_t* surface;
cairo_t* cr;
int last_delta_x = 0, last_delta_y = 0;
int drag_start_x, drag_start_y;
};
int main() {
Drawer d;
d.run();
return 0;
}
TL;DR: I don't see any leak.
Here is my version of the valgrind output (with a debug version of cairo and pixman (which means "with symbols"); (Oh and I also added a call to cairo_debug_reset_static_data()):
==4035== HEAP SUMMARY:
==4035== in use at exit: 86,640 bytes in 9 blocks
==4035== total heap usage: 6,736 allocs, 6,727 frees, 6,728,014 bytes allocated
==4035==
==4035== 128 bytes in 1 blocks are still reachable in loss record 1 of 9
==4035== at 0x4C28C4F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4035== by 0x4EA6044: cairo_pattern_create_for_surface (cairo-pattern.c:739)
==4035== by 0x4E6507F: _cairo_default_context_pop_group (cairo-default-context.c:238)
==4035== by 0x4E59E10: cairo_pop_group (cairo.c:554)
==4035== by 0x4E59E10: cairo_pop_group_to_source (cairo.c:594)
==4035== by 0x4017E0: Drawer::draw() (test.cpp:120)
==4035== by 0x40183E: Drawer::run() (test.cpp:129)
==4035== by 0x4013C6: main (test.cpp:144)
==4035==
==4035== 1,424 bytes in 1 blocks are still reachable in loss record 2 of 9
==4035== at 0x4C28C4F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4035== by 0x4E65D0B: _cairo_default_context_create (cairo-default-context.c:1463)
==4035== by 0x4014B8: Drawer::Drawer() (test.cpp:59)
==4035== by 0x4013BA: main (test.cpp:143)
==4035==
==4035== 2,064 bytes in 1 blocks are still reachable in loss record 3 of 9
==4035== at 0x4C28C4F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4035== by 0x636E8AA: _pixman_implementation_create (pixman-implementation.c:38)
==4035== by 0x636D3EE: _pixman_implementation_create_general (pixman-general.c:250)
==4035== by 0x636EF45: _pixman_choose_implementation (pixman-implementation.c:388)
==4035== by 0x63262C8: pixman_constructor (pixman.c:39)
==4035== by 0x400EA09: call_init.part.0 (dl-init.c:78)
==4035== by 0x400EAF2: call_init (dl-init.c:36)
==4035== by 0x400EAF2: _dl_init (dl-init.c:126)
==4035== by 0x40011C9: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==4035==
==4035== 2,064 bytes in 1 blocks are still reachable in loss record 4 of 9
==4035== at 0x4C28C4F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4035== by 0x636E8AA: _pixman_implementation_create (pixman-implementation.c:38)
==4035== by 0x636BF3F: _pixman_implementation_create_fast_path (pixman-fast-path.c:3286)
==4035== by 0x636EF60: _pixman_choose_implementation (pixman-implementation.c:391)
==4035== by 0x63262C8: pixman_constructor (pixman.c:39)
==4035== by 0x400EA09: call_init.part.0 (dl-init.c:78)
==4035== by 0x400EAF2: call_init (dl-init.c:36)
==4035== by 0x400EAF2: _dl_init (dl-init.c:126)
==4035== by 0x40011C9: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==4035==
==4035== 2,064 bytes in 1 blocks are still reachable in loss record 5 of 9
==4035== at 0x4C28C4F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4035== by 0x636E8AA: _pixman_implementation_create (pixman-implementation.c:38)
==4035== by 0x63871DF: _pixman_implementation_create_mmx (pixman-mmx.c:4021)
==4035== by 0x63543C5: _pixman_x86_get_implementations (pixman-x86.c:234)
==4035== by 0x636EF6B: _pixman_choose_implementation (pixman-implementation.c:393)
==4035== by 0x63262C8: pixman_constructor (pixman.c:39)
==4035== by 0x400EA09: call_init.part.0 (dl-init.c:78)
==4035== by 0x400EAF2: call_init (dl-init.c:36)
==4035== by 0x400EAF2: _dl_init (dl-init.c:126)
==4035== by 0x40011C9: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==4035==
==4035== 2,064 bytes in 1 blocks are still reachable in loss record 6 of 9
==4035== at 0x4C28C4F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4035== by 0x636E8AA: _pixman_implementation_create (pixman-implementation.c:38)
==4035== by 0x63A82BF: _pixman_implementation_create_sse2 (pixman-sse2.c:6487)
==4035== by 0x63543A5: _pixman_x86_get_implementations (pixman-x86.c:239)
==4035== by 0x636EF6B: _pixman_choose_implementation (pixman-implementation.c:393)
==4035== by 0x63262C8: pixman_constructor (pixman.c:39)
==4035== by 0x400EA09: call_init.part.0 (dl-init.c:78)
==4035== by 0x400EAF2: call_init (dl-init.c:36)
==4035== by 0x400EAF2: _dl_init (dl-init.c:126)
==4035== by 0x40011C9: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==4035==
==4035== 2,064 bytes in 1 blocks are still reachable in loss record 7 of 9
==4035== at 0x4C28C4F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4035== by 0x636E8AA: _pixman_implementation_create (pixman-implementation.c:38)
==4035== by 0x63A895F: _pixman_implementation_create_ssse3 (pixman-ssse3.c:345)
==4035== by 0x636EF6B: _pixman_choose_implementation (pixman-implementation.c:393)
==4035== by 0x63262C8: pixman_constructor (pixman.c:39)
==4035== by 0x400EA09: call_init.part.0 (dl-init.c:78)
==4035== by 0x400EAF2: call_init (dl-init.c:36)
==4035== by 0x400EAF2: _dl_init (dl-init.c:126)
==4035== by 0x40011C9: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==4035==
==4035== 2,064 bytes in 1 blocks are still reachable in loss record 8 of 9
==4035== at 0x4C28C4F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4035== by 0x636E8AA: _pixman_implementation_create (pixman-implementation.c:38)
==4035== by 0x63714CF: _pixman_implementation_create_noop (pixman-noop.c:155)
==4035== by 0x63262C8: pixman_constructor (pixman.c:39)
==4035== by 0x400EA09: call_init.part.0 (dl-init.c:78)
==4035== by 0x400EAF2: call_init (dl-init.c:36)
==4035== by 0x400EAF2: _dl_init (dl-init.c:126)
==4035== by 0x40011C9: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==4035==
==4035== 72,704 bytes in 1 blocks are still reachable in loss record 9 of 9
==4035== at 0x4C28C4F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4035== by 0x554E11F: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==4035== by 0x400EA09: call_init.part.0 (dl-init.c:78)
==4035== by 0x400EAF2: call_init (dl-init.c:36)
==4035== by 0x400EAF2: _dl_init (dl-init.c:126)
==4035== by 0x40011C9: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==4035==
==4035== LEAK SUMMARY:
==4035== definitely lost: 0 bytes in 0 blocks
==4035== indirectly lost: 0 bytes in 0 blocks
==4035== possibly lost: 0 bytes in 0 blocks
==4035== still reachable: 86,640 bytes in 9 blocks
==4035== suppressed: 0 bytes in 0 blocks
==4035==
==4035== For counts of detected and suppressed errors, rerun with: -v
==4035== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
No idea about the leaks in libstdc++, but since this in _dl_init, it should be harmless (one-time "leak" during startup).
The same holds for pixman_constructor: Pixman uses optimized code paths based on the CPU on which it runs. This is a one-time initialization that allocates memory that cannot be freed. It's harmless.
That leaves only two leaks. The pattern that is internally allocated in cairo_pop_group_to_source() isn't freed, but so is the cairo context created by cairo_create(). These leaks occurred because I mis-placed the call to cairo_debug_reset_static_data(). I was calling this in main which is before the destructor runs. Moving it to the destructor makes this leak disappear... Sorry for not noticing this earlier and sorry for being too lazy to update the above.
So for me there is an expected leak from pixman and an unexpected leak from libstdc++. Neither is related to cairo. I used cairo version 1.14.2-95-g98d01cd for this.
I'm trying to write a C program with Lua embedded inside.. And, I tried a very simple program to start, it just creates the Lua context, and then destroys it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
int main(int argc, char *argv[]) {
lua_State *L = lua_open();
luaL_openlibs(L);
lua_close(L);
fprintf(stderr, "%s: %d\n", __FILE__, __LINE__);
return(0);
}
I'm compiling it like so: (I'm actually using Torch7, so..)
g++ -c -g3 -O2 -Wall -Werror -I/usr/local/torch/install/include/ -fPIC pure_lua_test.C -o pure_lua_test.o
g++ -g3 -O2 -Wall -Werror -I/usr/local/torch/install/include/ -fPIC -o pure_lua_test pure_lua_test.o -L/usr/local/torch/install/lib/ -lluajit
When I run it on it's own, it prints
pure_lua_test.C: 16
as expected, (just before the return).
But, when I run it with valgrind, (as valgrind ./pure_lua_test )
I get
==9165== Memcheck, a memory error detector
==9165== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==9165== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==9165== Command: ./pure_lua_test
==9165==
==9165== Invalid read of size 4
==9165== at 0x4E9EE97: lua_pushcclosure (in /usr/local/src/torch-2015-05-25/install/lib/libluajit.so)
==9165== by 0x4EB4CDD: luaL_openlibs (in /usr/local/src/torch-2015-05-25/install/lib/libluajit.so)
==9165== by 0x400700: main (pure_lua_test.C:13)
==9165== Address 0x8 is not stack'd, malloc'd or (recently) free'd
==9165==
==9165==
==9165== Process terminating with default action of signal 11 (SIGSEGV)
==9165== Access not within mapped region at address 0x8
==9165== at 0x4E9EE97: lua_pushcclosure (in /usr/local/src/torch-2015-05-25/install/lib/libluajit.so)
==9165== by 0x4EB4CDD: luaL_openlibs (in /usr/local/src/torch-2015-05-25/install/lib/libluajit.so)
==9165== by 0x400700: main (pure_lua_test.C:13)
==9165== If you believe this happened as a result of a stack
==9165== overflow in your program's main thread (unlikely but
==9165== possible), you can try to increase the size of the
==9165== main thread stack using the --main-stacksize= flag.
==9165== The main thread stack size used in this run was 8388608.
==9165==
==9165== HEAP SUMMARY:
==9165== in use at exit: 0 bytes in 0 blocks
==9165== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==9165==
==9165== All heap blocks were freed -- no leaks are possible
==9165==
==9165== For counts of detected and suppressed errors, rerun with: -v
==9165== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Does anyone know what's happening? Why is it SIGSEGV'ing in valgrind? Is this something I should worry about? Basically, I was hoping to verify that a plugin I was writing for Torch had no memory leaks... But, if it fails with this, then, I'm kind of stuck.
The reason for this issue seems to be Valgrind, not LuaJIT. Valgrind is blocking MAP_32BIT which breaks LuaJIT. To demonstrate, add a check for NULL on lua_State * L and you'll see it is NULL while run under Valgrind, and non-NULL while running regularly.
Here is the modifications I did to your sample:
if(L == NULL) {
printf("Could not create luaL_newstate()\n");
} else {
luaL_openlibs(L);
lua_close(L);
printf("I can create luaL_newstate fine!\n");
}
When I run this normally:
$ ./pure_lua_test
I can create luaL_newstate fine!
But when I run it under Valgrind:
$ valgrind ./pure_lua_test
==8211== Memcheck, a memory error detector
==8211== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8211== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==8211== Command: ./pure_lua_test
==8211==
Could not create luaL_newstate()
==8211==
GDB also report that the application exited as it should:
(gdb) run
Starting program: /tmp/pure_lua_test
I can create luaL_newstate fine!
[Inferior 1 (process 8621) exited normally]
Here is a complete MCVE:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
int main(int argc, char *argv[]) {
lua_State *L;
L = luaL_newstate();
if(L == NULL) {
printf("Could not create luaL_newstate()\n");
} else {
luaL_openlibs(L);
lua_close(L);
printf("I can create luaL_newstate fine!\n");
}
return(0);
}
Here is a nice article on MAP_32BIT. Hope this helps in any way.
When I just run my program:ns-server everytime, it will show me that it decrypts message fail, but when I use valgrind try to find why this error happens, it works fine. Every time when I use valgrind to debug it, it works fine.
the valgrind result is :
valgrind --leak-check=yes ./ns-server
==44887== Memcheck, a memory error detector
==44887== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==44887== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==44887== Command: ./ns-server
==44887==
first get nextlen 564
nextlen is 564
==44887== Thread 2:
==44887== Invalid read of size 1
==44887== at 0x6C49: strlen (vg_replace_strmem.c:427)
==44887== by 0x100134E6F: StringBuffer::setString(char const*) (in ./ns-server)
==44887== by 0x100159A4F: XString::setFromAnsi(char const*) (in ./ns-server)
==44887== by 0x100025396: CkRsa::DecryptStringENC(char const*, bool, CkString&) (in ./ns-server)
==44887== by 0x1000130EA: My_RSA::MyDecryption(char*, CkString&) (RSAsample.cpp:52)
==44887== by 0x1000021C1: Server::Register(char*, int, char*) (Server.cpp:164)
==44887== by 0x100001EAB: Server::Evaluate_MSG(void*) (Server.cpp:75)
==44887== by 0x409898: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==44887== by 0x409729: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887== by 0x40DFC8: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887== Address 0x100b3f150 is 0 bytes after a block of size 128 alloc'd
==44887== at 0x47E1: malloc (vg_replace_malloc.c:300)
==44887== by 0x1000020F4: Server::Register(char*, int, char*) (Server.cpp:154)
==44887== by 0x100001EAB: Server::Evaluate_MSG(void*) (Server.cpp:75)
==44887== by 0x409898: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==44887== by 0x409729: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887== by 0x40DFC8: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==44887==
This is part of the result.
In this result, it mentions:
by 0x100134E6F: StringBuffer::setString(char const*) (in ./ns-server)
==44887== by 0x100159A4F: XString::setFromAnsi(char const*) (in ./ns-server)
==44887== by 0x100025396: CkRsa::DecryptStringENC(char const*, bool, CkString&) (in ./ns-server)
But these 3 functions come from static library which I download them from http://www.chilkatsoft.com/refdoc/vcCkRsaRef.html does this mean the error actually happen in these functions? Why when I run with valgrind, my project can output the right result?When I run it without any debugging tool, it will output "decrypt fail". Valgrind will change something related to my program?
My code is as follows:
int main(int argc, const char * argv[])
{
Server myServer(SERVER_PORT);//initialize server's port num,set up socket
myServer.Start();
return 0;
}
int Server::Start()
{
send_public_key server_pub_key;
server_pub_key.heads.random=random()%10;
server_pub_key.heads.request_type=PUBLICKEY;
server_pub_key.heads.length=sizeof(send_public_key);
strcpy(server_pub_key.pubkey,server_rsa.publickey);
TCPServer.SetupListen(PortListen,Evaluate_MSG,"",0,PUBLICKEY,(char *)&server_pub_key,server_pub_key.heads.length);
return 0;
}
int TCPConnect::SetupListen(int port, void * trifunc(void *),char * refuseMSG,int refuseLen,int pub,char *msg,int length)
{
if((mi_SocketToListen=socket(AF_INET,SOCK_STREAM,0))==-1)
{
printf("create socket failed\n");
return errno;
}
struct sockaddr_in ts_SocketAddrToListen;
ts_SocketAddrToListen.sin_addr.s_addr=INADDR_ANY;
SetupSocketAddrToTarget(NULL, port, ts_SocketAddrToListen,1);
if( bind(mi_SocketToListen,(struct sockaddr *)&ts_SocketAddrToListen,sizeof(struct sockaddr)) == -1)
{
printf("establish socket failed!\n");
return errno;
}
if(listen(mi_SocketToListen,99)==-1)
{
printf("listen failed\n");
return errno;
}
while (1)
{
int ti_sockfd;
struct sockaddr_in ts_sockaddr;
socklen_t ti_size = sizeof(struct sockaddr_in);
if((ti_sockfd=accept(mi_SocketToListen,(struct sockaddr *)&ts_sockaddr,&ti_size))==-1)
{
printf("accept user failed\n");
return errno;
}
if (threadlist.size() < mi_MaxConnection)
{
if(pub==80)//if this needs me to send a public key immediately afther i accept it
{
SendMsg(ti_sockfd, msg,length);
}
mm_clients.insert(std::pair<int,struct sockaddr_in>(ti_sockfd,ts_sockaddr));
pthread_t tp_threadfd;
pthread_create(&tp_threadfd,NULL,trifunc,(void *)&ti_sockfd);
threadlist.push_back(tp_threadfd);
}
else
{
SendMsg(ti_sockfd, refuseMSG, refuseLen);
CloseConnect(ti_sockfd,NULL);
}
}
return 0;
};
void * Server::Evaluate_MSG(void *arg)
{
int socketfd = *((int *) arg);
header checkheader;
int err;
while (true)
{
err = 0;
char * msg;
char *ip;
ip=(char *)malloc(sizeof(char)*INET_ADDRSTRLEN);
memset(ip,0,sizeof(char)*INET_ADDRSTRLEN);
int nextlen=Server::TCPServer.GetNextlen(socketfd);
msg=(char *)malloc(sizeof(char)*nextlen);
memset(msg,0,sizeof(char)*nextlen);
msg=Server::TCPServer.Receive(socketfd, nextlen);
//Server::TCPServer.Receive(socketfd,msg);
struct sockaddr_in sender_ip;
memset(&sender_ip,0,sizeof(struct sockaddr_in));
sender_ip=Server::TCPServer.GetInfoBySocket(socketfd);
inet_ntop(AF_INET,&sender_ip.sin_addr,ip,INET_ADDRSTRLEN);
memset(&checkheader,0,sizeof(header));
memcpy(&checkheader,msg,sizeof(header));
switch(checkheader.request_type)
{
case REGISTER:
err = Register(msg, socketfd,ip);
break;
case LOGIN:
err=Login(msg, socketfd,ip);
break;
default:
break;
}
free(ip);
free(msg);
if (err<0)
{
cout<<"error!"<<endl;
pthread_exit(0);
}
}
}
int Server::Register(char *msg,int sockfd,char *ip)
{
request_register reg;
memset(®,0,sizeof(request_register));
memcpy(®,msg,sizeof(request_register));
if(reg.real_pass!=REAL_PASS)
{
//ignore
}
else
{
send_user_success success_err;
success_err.heads.random=random()%10;
success_err.heads.length=sizeof(success_err);
CkString user_name_outData;
char *recv_username;
recv_username=(char *)malloc(sizeof(char)*LENGTH_CIPHERTEXT);
memset(recv_username,0,sizeof(char)*LENGTH_CIPHERTEXT);
memcpy(recv_username,reg.username,sizeof(char)*LENGTH_CIPHERTEXT);
server_rsa.MyDecryption(recv_username,user_name_outData);
//it decrypt fails
cout<<"after returning:"<<user_name_outData.getString()<<endl;
-------------------Above is part of function of Register(), it is too long, I just post part of it----------------
bool My_RSA::MyDecryption(char *ciphertext,CkString &outData)
{
rsaDecryptor.put_EncodingMode("hex");
rsaDecryptor.ImportPrivateKey(privatekey);
bool userPrivateKey;
userPrivateKey=true;
const char *cipher;
cipher=ciphertext;
const char * decryptedStr ;
decryptedStr= new char[SAY_MAX];
memset((char *)decryptedStr,0,sizeof(char)*SAY_MAX);
bool test=(char *) rsaDecryptor.DecryptStringENC(ciphertext, userPrivateKey, outData);//(decryptedStr, userPrivateKey);
if (!test) {
cout<<"decrypt failed"<<endl;
return false;
}
return true;
}
The error is: it will shows "decrypt failed" when I run without any debug tool, but it will decrypt definitely with valgrind.
This is header(part):
static std::map <string,struct user_info> user_info_map;//string is user's name
static My_RSA server_rsa;
class Server
{
public:
Server(int p);
protected:
static TCPConnect TCPServer;
public:
int PortListen;
protected:
static int Register(char *msg,int sockfd,char *ip);
static int Login(char *msg,int sockfd,char *ip);
static int Lock_Un_Out(char *msg,int sockfd,int lock_unlock);
static int Check_User(int sockfd);
static int Send_User(char *msg,int sockfd);
static int Update(char *msg,int sockfd);
public:
int Start();
static void * Evaluate_MSG(void *arg);
};
The error is part is that it decrypts fail, but I don't think it is related to the function of DecryptStringENC because when I run it with valgrind or Xcode, it works fine frequently.
Now I see why an error happens. When I pass ciphertext into MyDecryption(char *ciphertext,CkString &outData)
I set the size of it is 128bytes(Because when I use strlen to see the ciphertext's size, it shows 128). But I sudden think about that maybe I should malloc ciphertext with size of 129 bytes because '/0' will be attached to a string. Then, problem solves!!!!!!!
I have a toy project which is a game engine. It uses SDL2 and C++11. In the code below I tried to make an objects which cleans memory after itself in destructor. But something goes wrong and some memory leaks. What am I doing wrong?
Example is minimal working code which triggers a leak. I suppose it works like this:
Instance of class Game upon costruction creates instances of SDLEngine and Graphics (in this order), both of which allocates some memory too. When game object is destroyed it calls destructors of Graphics and SDLEngine (in this order). If I add some printing in both of this destructors they are printed in the needed order. But valgrind thinks that memory allocated by SDL_Init() and SDL_CreateWindow() are leaked.
Edit: it is probably valgrind behaviour. I saw a similar question and similar warnings in the pretty basic SDL example: Why does valgrind say basic SDL program is leaking memory?
src/leak-test.cpp:
#include <SDL2/SDL.h>
#include <stdexcept>
class SDLEngine {
public:
SDLEngine() {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
throw std::runtime_error("SDL_Init"); // line 7
}
if (SDL_ShowCursor(SDL_DISABLE) < 0) {
throw std::runtime_error("SDL_ShowCursor");
}
}
~SDLEngine() {
SDL_Quit();
}
};
class Graphics {
public:
Graphics() :
sdlWindow{SDL_CreateWindow(
"LeakTest",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
320, 240,
0
)} // line 27
{
if (sdlWindow == nullptr) {
throw std::runtime_error("SDL_CreateWindow");
}
}
~Graphics() {
SDL_DestroyWindow(sdlWindow);
}
Graphics(const Graphics&)=delete;
Graphics& operator=(const Graphics&)=delete;
private:
SDL_Window *sdlWindow;
};
class Game {
public:
Game() :
sdlEngine_(),
graphics_() // line 46
{
SDL_Event event;
bool running{true};
while (running) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
running = false;
break;
default:
break;
}
}
}
}
~Game() {}
private:
const SDLEngine sdlEngine_;
Graphics graphics_;
};
int main() {
Game game; // line 70
return 0;
}
Makefile:
CXX := g++
MKDIR := mkdir -p
CXXFLAGS += `pkg-config --cflags sdl2 SDL2_image`
CXXFLAGS += -Wall -Werror -Wextra -Weffc++ -pedantic -std=c++0x -g
LDFLAGS += `pkg-config --libs sdl2 SDL2_image`
PROG := bin/leak-test
OBJS := $(patsubst src/%.cpp,obj/%.o, $(wildcard src\/*.cpp))
# escaped to fool SO parser ^
.PHONY: all clean
all: build
build: $(PROG)
clean:
rm -rf $(PROG) $(OBJS)
$(PROG): obj/leak-test.o
$(PROG):
#$(MKDIR) $(dir $#)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $# $^
obj/%.o : src/%.cpp
#$(MKDIR) $(dir $#)
$(CXX) $(CXXFLAGS) -c -MD -o $# $<
Valgrind output:
host:cave-test ยป valgrind --leak-check=full ./bin/leak-test
==28815== Memcheck, a memory error detector
==28815== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==28815== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==28815== Command: ./bin/leak-test
==28815==
==28815==
==28815== HEAP SUMMARY:
==28815== in use at exit: 66,235 bytes in 506 blocks
==28815== total heap usage: 19,844 allocs, 19,338 frees, 44,931,400 bytes allocated
==28815==
==28815== 20 bytes in 2 blocks are definitely lost in loss record 7 of 101
==28815== at 0x4C274A0: malloc (vg_replace_malloc.c:291)
==28815== by 0x5BF8829: strdup (strdup.c:42)
==28815== by 0x7203666: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x7204474: _XimSetICValueData (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x71FFA69: _XimLocalCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x71E6044: XCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x5111CD2: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x51120F7: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x51055FF: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x510540F: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x507048E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x400D6E: SDLEngine::SDLEngine() (leak-test.cpp:7)
==28815==
==28815== 20 bytes in 2 blocks are definitely lost in loss record 8 of 101
==28815== at 0x4C274A0: malloc (vg_replace_malloc.c:291)
==28815== by 0x5BF8829: strdup (strdup.c:42)
==28815== by 0x7203666: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x7204474: _XimSetICValueData (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x71FFA69: _XimLocalCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x71E6044: XCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x5111CD2: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x51120F7: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x51055FF: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x400F11: Graphics::Graphics() (leak-test.cpp:27)
==28815== by 0x401012: Game::Game() (leak-test.cpp:46)
==28815== by 0x400D31: main (leak-test.cpp:70)
==28815==
==28815== 104 bytes in 1 blocks are definitely lost in loss record 60 of 101
==28815== at 0x4C274A0: malloc (vg_replace_malloc.c:291)
==28815== by 0xD330A11: ??? (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815== by 0xD309600: ??? (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815== by 0xD305E7A: ??? (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815== by 0xD30660F: glXChooseVisual (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815== by 0x510ED0E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x510EF40: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x5103B65: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x51056FB: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x510540F: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x507048E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x400D6E: SDLEngine::SDLEngine() (leak-test.cpp:7)
==28815==
==28815== LEAK SUMMARY:
==28815== definitely lost: 144 bytes in 5 blocks
==28815== indirectly lost: 0 bytes in 0 blocks
==28815== possibly lost: 0 bytes in 0 blocks
==28815== still reachable: 66,091 bytes in 501 blocks
==28815== suppressed: 0 bytes in 0 blocks
==28815== Reachable blocks (those to which a pointer was found) are not shown.
==28815== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==28815==
==28815== For counts of detected and suppressed errors, rerun with: -v
==28815== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 7 from 3)
It turns out this leak belongs to layer under SDL, in the X11 library. This bug is very old and known by SDL devs. See this bugzilla thread: https://bugzilla.libsdl.org/show_bug.cgi?id=2086
I close the question now.
I understand from other questions on SO that this warning should not be taken lightly.
It appears to originate from the curl_easy_perform method.
main.cpp:
#include <iostream>
#include <stdio.h>
#include <curl/curl.h>
std::string data;
size_t writeCallback(char* buf, size_t size, size_t nmemb, void* up)
{
for (int c = 0; c<size*nmemb; c++)
{
data.push_back(buf[c]);
}
return size*nmemb;
}
int main( void )
{
curl_global_init ( CURL_GLOBAL_DEFAULT );
CURL * curl;
CURLcode res;
struct curl_slist * chunk = NULL;
chunk = curl_slist_append(chunk, "X-Mashape-Authorization: XXXYYYYZZZZ" );
curl = curl_easy_init ( ) ;
if( curl )
{
std::string _query = "text=Hello";
curl_easy_setopt ( curl, CURLOPT_URL, "https://japerk-text-processing.p.mashape.com/tag/" );
curl_easy_setopt ( curl, CURLOPT_POSTFIELDS, _query.c_str() );
curl_easy_setopt ( curl, CURLOPT_WRITEFUNCTION, writeCallback );
curl_easy_setopt ( curl, CURLOPT_FOLLOWLOCATION, 1L );
#ifdef SKIP_PEER_VERIFICATION
curl_easy_setopt ( curl, CURLOPT_SSL_VERIFYPEER, 0L );
#endif
#ifdef SKIP_HOSTNAME_VERIFICATION
curl_easy_setopt ( curl, CURLOPT_SSL_VERIFYHOST, 0L );
#endif
res = curl_easy_setopt ( curl, CURLOPT_HTTPHEADER, chunk );
res = curl_easy_perform ( curl ); // BUG: Conditional jump or move depends on uninitialised value(s)
curl_slist_free_all( chunk );
if(res != CURLE_OK)
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
Running with valgrind
==4443== Memcheck, a memory error detector
==4443== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==4443== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==4443== Command: ./CURLTest
==4443==
==4443== Thread 2:
==4443== Syscall param sendmsg(mmsg[0].msg_hdr) points to uninitialised byte(s)
==4443== at 0x59A170B: sendmmsg (sendmmsg.c:36)
==4443== by 0x86652DE: __libc_res_nsend (res_send.c:1140)
==4443== by 0x8662B8B: __libc_res_nquery (res_query.c:226)
==4443== by 0x8663147: __libc_res_nquerydomain (res_query.c:582)
==4443== by 0x8663746: __libc_res_nsearch (res_query.c:378)
==4443== by 0xA2FFA35: _nss_dns_gethostbyname4_r (dns-host.c:314)
==4443== by 0x597B631: gaih_inet (getaddrinfo.c:849)
==4443== by 0x597EA13: getaddrinfo (getaddrinfo.c:2473)
==4443== by 0x4E77483: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==4443== by 0x4E82F73: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==4443== by 0x4E8089A: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==4443== by 0x78F4E0D: start_thread (pthread_create.c:311)
==4443== Address 0x9eeb020 is on thread 2's stack
==4443==
==4443== Thread 1:
==4443== Conditional jump or move depends on uninitialised value(s)
==4443== at 0x6304908: ??? (in /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0)
==4443== by 0x62FB572: ??? (in /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0)
==4443== by 0x62F8BF5: ??? (in /usr/lib/x86_64-linux-gnu/libssl.so.1.0.0)
==4443== by 0x4E57CAB: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==4443== by 0x4E48C3A: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==4443== by 0x4E60832: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==4443== by 0x4E6A917: ??? (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==4443== by 0x4E6B070: curl_multi_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==4443== by 0x4E62906: curl_easy_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==4443== by 0x40130C: main (in /CURLTest/CURLTest)
GCC 4.8.2
valgrind 3.8.1
libcurl 4.3.0
Could some please help?
Is this a false positive, can I ignore it or could it lead to problems?
Thanks