You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@qpid.apache.org by Tony Ercolano <to...@microsoft.com> on 2015/03/19 00:34:17 UTC

Ubuntu/OpenSSL failure when creating two messengers each in a separate thread.

I have some code that is attempting on Ubuntu to create two different messengers to talk with two different entities.

Each messenger is created in its own separate thread and will ONLY be accessed by that thread.

However, I'm getting a failure from OpenSSL.   See below.  NOTE: Both of these threads are likely running in lockstep.

Is it the convention that a user of the proton-c library needs to somehow protect against two separate threads creating messengers at the same time? I've include (at the bottom) a .c file that consistently demonstrates this issue.

myuser@myubuntu:~/qpid-proton/build/examples/messenger/c$ ./send
*** Error in `./send': double free or corruption (!prev): 0x00007f249c014ae0 ***
Aborted (core dumped)
myuser@myubuntu:~/qpid-proton/build/examples/messenger/c$ sudo gdb ./send core
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./send...done.

warning: exec file is newer than core file.
[New LWP 17309]
[New LWP 17310]
[New LWP 17308]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./send'.
Program terminated with signal SIGABRT, Aborted.
#0  0x00007ff73e3e8cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56           ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ff73e3e8cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ff73e3ec0d8 in __GI_abort () at abort.c:89
#2  0x00007ff73e425394 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ff73e533b28 "*** Error in `%s': %s: 0x%s ***\n")
    at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ff73e43166e in malloc_printerr (ptr=<optimized out>, str=0x7ff73e533c10 "double free or corruption (!prev)", action=1) at malloc.c:4996
#4  _int_free (av=<optimized out>, p=<optimized out>, have_lock=1) at malloc.c:3840
#5  0x00007ff73e433890 in _int_realloc (av=0x7ff730000020, oldp=0x7ff730015970, oldsize=272, nb=528) at malloc.c:4340
#6  0x00007ff73e434fc9 in __GI___libc_realloc (oldmem=0x7ff730015980, bytes=512) at malloc.c:3029
#7  0x00007ff73dbd4e29 in CRYPTO_realloc () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#8  0x00007ff73dc5abc1 in lh_insert () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#9  0x00007ff73dc5d0fa in ?? () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#10 0x00007ff73dc5cb0b in ?? () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#11 0x00007ff73dc5d36f in ERR_load_ERR_strings () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#12 0x00007ff73dc5e3d9 in ERR_load_crypto_strings () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#13 0x00007ff73df89479 in SSL_load_error_strings () from /lib/x86_64-linux-gnu/libssl.so.1.0.0
#14 0x00007ff73e9c9be5 in pn_ssl_domain (mode=mode@entry=PN_SSL_MODE_CLIENT) at /home/myuser/qpid-proton/proton-c/src/ssl/openssl.c:443
#15 0x00007ff73e9c0b7a in pn_transport_config (messenger=messenger@entry=0x7ff738003320, connection=connection@entry=0x7ff738006530)
    at /home/myuser/qpid-proton/proton-c/src/messenger/messenger.c:928
#16 0x00007ff73e9c2b39 in pn_messenger_resolve (messenger=messenger@entry=0x7ff738003320,
    address=address@entry=0x7ff738003210 "amqps://<snip>"..., name=name@entry=0x7ff73d96fe08)
    at /home/myuser/qpid-proton/proton-c/src/messenger/messenger.c:1667
#17 0x00007ff73e9c2d0d in pn_messenger_link (messenger=messenger@entry=0x7ff738003320,
    address=address@entry=0x7ff738003210 "amqps://<snip>"..., sender=sender@entry=true, timeout=timeout@entry=0)
    at /home/myuser/qpid-proton/proton-c/src/messenger/messenger.c:1706
#18 0x00007ff73e9c2ffc in pn_messenger_target (messenger=messenger@entry=0x7ff738003320,
    target=target@entry=0x7ff738003210 "amqps://<snip>"..., timeout=timeout@entry=0)
    at /home/myuser/qpid-proton/proton-c/src/messenger/messenger.c:1773
#19 0x00007ff73e9c376e in pn_messenger_put (messenger=messenger@entry=0x7ff738003320, msg=msg@entry=0x7ff7380008d0)
    at /home/myuser/qpid-proton/proton-c/src/messenger/messenger.c:1974
#20 0x00000000004011a1 in thread_routine (arg=<optimized out>) at /home/myuser/qpid-proton/examples/messenger/c/send.c:69
#21 0x00007ff73e77f182 in start_thread (arg=0x7ff73d970700) at pthread_create.c:312
#22 0x00007ff73e4ac47d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111


/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/

#include "proton/message.h"
#include "proton/messenger.h"

#include "pncompat/misc_funcs.inc"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <pthread.h>

#define check(messenger)                                                     \
  {                                                                          \
    if(pn_messenger_errno(messenger))                                        \
    {                                                                        \
      die(__FILE__, __LINE__, pn_error_text(pn_messenger_error(messenger))); \
    }                                                                        \
  }                                                                          \

void die(const char *file, int line, const char *message)
{
  fprintf(stderr, "%s:%i: %s\n", file, line, message);
  exit(1);
}

typedef struct
{
    const char* address;
    const char* msgtext;
} thread_arg;

void* thread_routine(void* arg)
{
  thread_arg* info = (thread_arg*)arg;

  pn_message_t * message;
  pn_messenger_t * messenger;
  pn_data_t * body;

  message = pn_message();
  pn_message_set_address(message, info->address);
  pn_message_set_inferred(message, true);
  body = pn_message_body(message);
  pn_data_put_binary(body, pn_bytes(strlen(info->msgtext), info->msgtext));

  messenger = pn_messenger(NULL);
  pn_messenger_start(messenger);

  pn_messenger_put(messenger, message);
  check(messenger);

  pn_messenger_send(messenger, -1);
  check(messenger);

  pn_messenger_stop(messenger);
  pn_messenger_free(messenger);
  pn_message_free(message);

  return NULL;
}

int main(int argc, char** argv)
{
  const char* address1 = "amqps://<snip>";
  const char* address2 = "amqps://<snip>";
  const char* msgtext1 = "1:hello world";
  const char* msgtext2 = "2:hello world";

  thread_arg arg1 = { address1, msgtext1 };
  thread_arg arg2 = { address2, msgtext2 };

  pthread_t thread1;
  pthread_t thread2;

  int result;
  result = pthread_create(&thread1, NULL, thread_routine, (void*)&arg1);
  result = pthread_create(&thread2, NULL, thread_routine, (void*)&arg2);

  pthread_join(thread1, NULL);
  pthread_join(thread2, NULL);

  return 0;
}