2001-12-19 07:46:35 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2005-05-03 11:33:49 +04:00
local testing of talloc routines .
Copyright ( C ) Andrew Tridgell 2004
2001-12-19 07:46:35 +03:00
2006-08-31 11:42:47 +04:00
* * NOTE ! The following LGPL license applies to the talloc
* * library . This does NOT imply that all of Samba is released
* * under the LGPL
2001-12-19 07:46:35 +03:00
2006-08-31 11:42:47 +04:00
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation ; either
2007-07-10 05:44:42 +04:00
version 3 of the License , or ( at your option ) any later version .
2006-08-31 11:42:47 +04:00
This library is distributed in the hope that it will be useful ,
2001-12-19 07:46:35 +03:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2006-08-31 11:42:47 +04:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public
2007-07-10 07:42:26 +04:00
License along with this library ; if not , see < http : //www.gnu.org/licenses/>.
2001-12-19 07:46:35 +03:00
*/
2006-09-22 08:16:58 +04:00
# include "replace.h"
# include "system/time.h"
2010-03-29 11:48:29 +04:00
# include <talloc.h>
2005-05-03 11:33:49 +04:00
2015-03-16 22:18:17 +03:00
# ifdef HAVE_PTHREAD
# include <pthread.h>
# endif
2015-09-02 04:30:31 +03:00
# include <unistd.h>
# include <sys/wait.h>
2016-10-12 13:18:11 +03:00
# ifdef NDEBUG
# undef NDEBUG
# endif
# include <assert.h>
2011-01-02 04:33:12 +03:00
# include "talloc_testsuite.h"
2016-06-01 16:42:13 +03:00
static struct timeval private_timeval_current ( void )
2006-08-31 11:42:47 +04:00
{
struct timeval tv ;
gettimeofday ( & tv , NULL ) ;
return tv ;
}
2005-05-03 11:33:49 +04:00
2016-06-01 16:42:13 +03:00
static double private_timeval_elapsed ( struct timeval * tv )
2005-05-03 11:33:49 +04:00
{
2016-06-01 16:42:13 +03:00
struct timeval tv2 = private_timeval_current ( ) ;
2005-05-03 11:33:49 +04:00
return ( tv2 . tv_sec - tv - > tv_sec ) +
( tv2 . tv_usec - tv - > tv_usec ) * 1.0e-6 ;
}
2006-10-21 04:23:27 +04:00
# define torture_assert(test, expr, str) if (!(expr)) { \
printf ( " failure: %s [ \n %s: Expression %s failed: %s \n ] \n " , \
test , __location__ , # expr , str ) ; \
return false ; \
}
# define torture_assert_str_equal(test, arg1, arg2, desc) \
2019-05-02 02:29:34 +03:00
if ( arg1 = = NULL & & arg2 = = NULL ) { /* OK, both NULL == equal */ \
} else if ( arg1 = = NULL | | arg2 = = NULL ) { \
return false ; \
2008-04-17 13:22:23 +04:00
} else if ( strcmp ( arg1 , arg2 ) ) { \
2006-10-21 04:23:27 +04:00
printf ( " failure: %s [ \n %s: Expected %s, got %s: %s \n ] \n " , \
test , __location__ , arg1 , arg2 , desc ) ; \
return false ; \
}
# define CHECK_SIZE(test, ptr, tsize) do { \
2005-05-03 11:33:49 +04:00
if ( talloc_total_size ( ptr ) ! = ( tsize ) ) { \
2009-07-13 22:34:10 +04:00
printf ( " failed: %s [ \n %s: wrong '%s' tree size: got %u expected %u \n ] \n " , \
test , __location__ , # ptr , \
2005-05-03 11:33:49 +04:00
( unsigned ) talloc_total_size ( ptr ) , \
( unsigned ) tsize ) ; \
talloc_report_full ( ptr , stdout ) ; \
2006-09-22 08:16:58 +04:00
return false ; \
2005-05-03 11:33:49 +04:00
} \
} while ( 0 )
2006-10-21 04:23:27 +04:00
# define CHECK_BLOCKS(test, ptr, tblocks) do { \
2005-05-03 11:33:49 +04:00
if ( talloc_total_blocks ( ptr ) ! = ( tblocks ) ) { \
2009-07-13 22:34:10 +04:00
printf ( " failed: %s [ \n %s: wrong '%s' tree blocks: got %u expected %u \n ] \n " , \
test , __location__ , # ptr , \
2005-05-03 11:33:49 +04:00
( unsigned ) talloc_total_blocks ( ptr ) , \
( unsigned ) tblocks ) ; \
talloc_report_full ( ptr , stdout ) ; \
2006-09-22 08:16:58 +04:00
return false ; \
2005-05-03 11:33:49 +04:00
} \
} while ( 0 )
2001-12-19 07:46:35 +03:00
2006-10-21 04:23:27 +04:00
# define CHECK_PARENT(test, ptr, parent) do { \
2006-08-31 11:42:47 +04:00
if ( talloc_parent ( ptr ) ! = ( parent ) ) { \
2009-07-13 22:34:10 +04:00
printf ( " failed: %s [ \n %s: '%s' has wrong parent: got %p expected %p \n ] \n " , \
test , __location__ , # ptr , \
2006-08-31 11:42:47 +04:00
talloc_parent ( ptr ) , \
( parent ) ) ; \
talloc_report_full ( ptr , stdout ) ; \
talloc_report_full ( parent , stdout ) ; \
talloc_report_full ( NULL , stdout ) ; \
2006-09-22 08:16:58 +04:00
return false ; \
2006-08-31 11:42:47 +04:00
} \
} while ( 0 )
2009-07-14 13:58:16 +04:00
static unsigned int test_abort_count ;
2011-01-02 04:33:12 +03:00
#if 0
2009-07-14 13:58:16 +04:00
static void test_abort_fn ( const char * reason )
{
printf ( " # test_abort_fn(%s) \n " , reason ) ;
test_abort_count + + ;
}
static void test_abort_start ( void )
{
test_abort_count = 0 ;
talloc_set_abort_fn ( test_abort_fn ) ;
}
2011-01-02 04:33:12 +03:00
# endif
2009-07-14 13:58:16 +04:00
static void test_abort_stop ( void )
{
test_abort_count = 0 ;
talloc_set_abort_fn ( NULL ) ;
}
2001-12-19 07:46:35 +03:00
2009-07-30 00:00:05 +04:00
static void test_log_stdout ( const char * message )
{
fprintf ( stdout , " %s " , message ) ;
}
2005-05-03 11:33:49 +04:00
/*
test references
*/
2006-09-22 08:16:58 +04:00
static bool test_ref1 ( void )
2001-12-19 07:46:35 +03:00
{
2005-05-03 11:33:49 +04:00
void * root , * p1 , * p2 , * ref , * r1 ;
2007-09-19 18:44:16 +04:00
printf ( " test: ref1 \n # SINGLE REFERENCE FREE \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " p1 " ) ;
p2 = talloc_named_const ( p1 , 1 , " p2 " ) ;
talloc_named_const ( p1 , 1 , " x1 " ) ;
talloc_named_const ( p1 , 2 , " x2 " ) ;
talloc_named_const ( p1 , 3 , " x3 " ) ;
r1 = talloc_named_const ( root , 1 , " r1 " ) ;
ref = talloc_reference ( r1 , p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2001-12-19 07:46:35 +03:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref1 " , p1 , 5 ) ;
CHECK_BLOCKS ( " ref1 " , p2 , 1 ) ;
2014-02-27 12:28:02 +04:00
CHECK_BLOCKS ( " ref1 " , ref , 1 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref1 " , r1 , 2 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing p2 \n " ) ;
2009-07-01 10:36:29 +04:00
talloc_unlink ( r1 , p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref1 " , p1 , 5 ) ;
CHECK_BLOCKS ( " ref1 " , p2 , 1 ) ;
CHECK_BLOCKS ( " ref1 " , r1 , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing p1 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p1 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref1 " , r1 , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing r1 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( r1 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( NULL , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Testing NULL \n " ) ;
2005-05-03 11:33:49 +04:00
if ( talloc_reference ( root , NULL ) ) {
2006-09-22 08:16:58 +04:00
return false ;
2001-12-19 07:46:35 +03:00
}
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref1 " , root , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " ref1 " , root , 0 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2006-10-21 04:23:27 +04:00
printf ( " success: ref1 \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
/*
test references
*/
2006-09-22 08:16:58 +04:00
static bool test_ref2 ( void )
2005-05-03 11:33:49 +04:00
{
void * root , * p1 , * p2 , * ref , * r1 ;
2007-09-19 18:44:16 +04:00
printf ( " test: ref2 \n # DOUBLE REFERENCE FREE \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " p1 " ) ;
talloc_named_const ( p1 , 1 , " x1 " ) ;
talloc_named_const ( p1 , 1 , " x2 " ) ;
talloc_named_const ( p1 , 1 , " x3 " ) ;
p2 = talloc_named_const ( p1 , 1 , " p2 " ) ;
r1 = talloc_named_const ( root , 1 , " r1 " ) ;
ref = talloc_reference ( r1 , p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref2 " , p1 , 5 ) ;
CHECK_BLOCKS ( " ref2 " , p2 , 1 ) ;
CHECK_BLOCKS ( " ref2 " , r1 , 2 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing ref \n " ) ;
2009-07-01 10:36:29 +04:00
talloc_unlink ( r1 , ref ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref2 " , p1 , 5 ) ;
CHECK_BLOCKS ( " ref2 " , p2 , 1 ) ;
CHECK_BLOCKS ( " ref2 " , r1 , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing p2 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref2 " , p1 , 4 ) ;
CHECK_BLOCKS ( " ref2 " , r1 , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing p1 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p1 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref2 " , r1 , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing r1 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( r1 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " ref2 " , root , 0 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2006-10-21 04:23:27 +04:00
printf ( " success: ref2 \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
/*
test references
*/
2006-09-22 08:16:58 +04:00
static bool test_ref3 ( void )
2005-05-03 11:33:49 +04:00
{
void * root , * p1 , * p2 , * ref , * r1 ;
2007-09-19 18:44:16 +04:00
printf ( " test: ref3 \n # PARENT REFERENCE FREE \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " p1 " ) ;
p2 = talloc_named_const ( root , 1 , " p2 " ) ;
r1 = talloc_named_const ( p1 , 1 , " r1 " ) ;
ref = talloc_reference ( p2 , r1 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref3 " , p1 , 2 ) ;
CHECK_BLOCKS ( " ref3 " , p2 , 2 ) ;
CHECK_BLOCKS ( " ref3 " , r1 , 1 ) ;
2014-02-27 12:28:02 +04:00
CHECK_BLOCKS ( " ref3 " , ref , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing p1 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p1 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref3 " , p2 , 2 ) ;
CHECK_BLOCKS ( " ref3 " , r1 , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing p2 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " ref3 " , root , 0 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
printf ( " success: ref3 \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
/*
test references
*/
2006-09-22 08:16:58 +04:00
static bool test_ref4 ( void )
2005-05-03 11:33:49 +04:00
{
void * root , * p1 , * p2 , * ref , * r1 ;
2007-09-19 18:44:16 +04:00
printf ( " test: ref4 \n # REFERRER REFERENCE FREE \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " p1 " ) ;
talloc_named_const ( p1 , 1 , " x1 " ) ;
talloc_named_const ( p1 , 1 , " x2 " ) ;
talloc_named_const ( p1 , 1 , " x3 " ) ;
p2 = talloc_named_const ( p1 , 1 , " p2 " ) ;
2001-12-19 07:46:35 +03:00
2005-05-03 11:33:49 +04:00
r1 = talloc_named_const ( root , 1 , " r1 " ) ;
ref = talloc_reference ( r1 , p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2001-12-19 11:18:07 +03:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref4 " , p1 , 5 ) ;
CHECK_BLOCKS ( " ref4 " , p2 , 1 ) ;
2014-02-27 12:28:02 +04:00
CHECK_BLOCKS ( " ref4 " , ref , 1 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref4 " , r1 , 2 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing r1 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( r1 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref4 " , p1 , 5 ) ;
CHECK_BLOCKS ( " ref4 " , p2 , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing p2 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " ref4 " , p1 , 4 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing p1 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p1 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " ref4 " , root , 0 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
printf ( " success: ref4 \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
/*
test references
*/
2006-09-22 08:16:58 +04:00
static bool test_unlink1 ( void )
2005-05-03 11:33:49 +04:00
{
void * root , * p1 , * p2 , * ref , * r1 ;
2007-09-19 18:44:16 +04:00
printf ( " test: unlink \n # UNLINK \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " p1 " ) ;
talloc_named_const ( p1 , 1 , " x1 " ) ;
talloc_named_const ( p1 , 1 , " x2 " ) ;
talloc_named_const ( p1 , 1 , " x3 " ) ;
p2 = talloc_named_const ( p1 , 1 , " p2 " ) ;
r1 = talloc_named_const ( p1 , 1 , " r1 " ) ;
ref = talloc_reference ( r1 , p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " unlink " , p1 , 7 ) ;
CHECK_BLOCKS ( " unlink " , p2 , 1 ) ;
2014-02-27 12:28:02 +04:00
CHECK_BLOCKS ( " unlink " , ref , 1 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " unlink " , r1 , 2 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Unreferencing r1 \n " ) ;
2005-05-03 11:33:49 +04:00
talloc_unlink ( r1 , p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " unlink " , p1 , 6 ) ;
CHECK_BLOCKS ( " unlink " , p2 , 1 ) ;
CHECK_BLOCKS ( " unlink " , r1 , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
fprintf ( stderr , " Freeing p1 \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p1 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " unlink " , root , 0 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
printf ( " success: unlink \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
static int fail_destructor ( void * ptr )
{
return - 1 ;
}
/*
miscellaneous tests to try to get a higher test coverage percentage
*/
2006-09-22 08:16:58 +04:00
static bool test_misc ( void )
2005-05-03 11:33:49 +04:00
{
void * root , * p1 ;
char * p2 ;
double * d ;
2006-08-31 11:42:47 +04:00
const char * name ;
2005-05-03 11:33:49 +04:00
2007-09-19 18:44:16 +04:00
printf ( " test: misc \n # MISCELLANEOUS \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_new ( NULL ) ;
p1 = talloc_size ( root , 0x7fffffff ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , ! p1 , " failed: large talloc allowed \n " ) ;
2005-05-03 11:33:49 +04:00
p1 = talloc_strdup ( root , " foo " ) ;
talloc_increase_ref_count ( p1 ) ;
talloc_increase_ref_count ( p1 ) ;
talloc_increase_ref_count ( p1 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " misc " , p1 , 1 ) ;
CHECK_BLOCKS ( " misc " , root , 2 ) ;
2009-07-01 10:36:29 +04:00
talloc_unlink ( NULL , p1 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " misc " , p1 , 1 ) ;
CHECK_BLOCKS ( " misc " , root , 2 ) ;
2005-05-03 11:33:49 +04:00
talloc_unlink ( NULL , p1 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " misc " , p1 , 1 ) ;
CHECK_BLOCKS ( " misc " , root , 2 ) ;
2005-05-03 11:33:49 +04:00
p2 = talloc_strdup ( p1 , " foo " ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , talloc_unlink ( root , p2 ) = = - 1 ,
" failed: talloc_unlink() of non-reference context should return -1 \n " ) ;
torture_assert ( " misc " , talloc_unlink ( p1 , p2 ) = = 0 ,
" failed: talloc_unlink() of parent should succeed \n " ) ;
2009-07-01 10:36:29 +04:00
talloc_unlink ( NULL , p1 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " misc " , p1 , 1 ) ;
CHECK_BLOCKS ( " misc " , root , 2 ) ;
2005-05-03 11:33:49 +04:00
2006-08-31 11:42:47 +04:00
name = talloc_set_name ( p1 , " my name is %s " , " foo " ) ;
2006-10-21 04:23:27 +04:00
torture_assert_str_equal ( " misc " , talloc_get_name ( p1 ) , " my name is foo " ,
" failed: wrong name after talloc_set_name(my name is foo) " ) ;
2014-02-27 12:28:02 +04:00
torture_assert_str_equal ( " misc " , talloc_get_name ( p1 ) , name ,
" failed: wrong name after talloc_set_name(my name is foo) " ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " misc " , p1 , 2 ) ;
CHECK_BLOCKS ( " misc " , root , 3 ) ;
2005-05-03 11:33:49 +04:00
talloc_set_name_const ( p1 , NULL ) ;
2006-10-21 04:23:27 +04:00
torture_assert_str_equal ( " misc " , talloc_get_name ( p1 ) , " UNNAMED " ,
" failed: wrong name after talloc_set_name(NULL) " ) ;
CHECK_BLOCKS ( " misc " , p1 , 2 ) ;
CHECK_BLOCKS ( " misc " , root , 3 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , talloc_free ( NULL ) = = - 1 ,
" talloc_free(NULL) should give -1 \n " ) ;
2005-05-03 11:33:49 +04:00
talloc_set_destructor ( p1 , fail_destructor ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , talloc_free ( p1 ) = = - 1 ,
" Failed destructor should cause talloc_free to fail \n " ) ;
2005-05-03 11:33:49 +04:00
talloc_set_destructor ( p1 , NULL ) ;
2006-10-21 04:23:27 +04:00
talloc_report ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-08-17 15:54:23 +04:00
p2 = ( char * ) talloc_zero_size ( p1 , 20 ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , p2 [ 19 ] = = 0 , " Failed to give zero memory \n " ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p2 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , talloc_strdup ( root , NULL ) = = NULL ,
" failed: strdup on NULL should give NULL \n " ) ;
2001-12-19 07:46:35 +03:00
2005-05-03 11:33:49 +04:00
p2 = talloc_strndup ( p1 , " foo " , 2 ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , strcmp ( " fo " , p2 ) = = 0 ,
" strndup doesn't work \n " ) ;
2007-09-19 18:44:16 +04:00
p2 = talloc_asprintf_append_buffer ( p2 , " o%c " , ' d ' ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , strcmp ( " food " , p2 ) = = 0 ,
2007-09-19 18:44:16 +04:00
" talloc_asprintf_append_buffer doesn't work \n " ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " misc " , p2 , 1 ) ;
CHECK_BLOCKS ( " misc " , p1 , 3 ) ;
2005-05-03 11:33:49 +04:00
2007-09-19 18:44:16 +04:00
p2 = talloc_asprintf_append_buffer ( NULL , " hello %s " , " world " ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , strcmp ( " hello world " , p2 ) = = 0 ,
2007-09-19 18:44:16 +04:00
" talloc_asprintf_append_buffer doesn't work \n " ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " misc " , p2 , 1 ) ;
CHECK_BLOCKS ( " misc " , p1 , 3 ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p2 ) ;
2005-05-03 11:33:49 +04:00
d = talloc_array ( p1 , double , 0x20000000 ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , ! d , " failed: integer overflow not detected \n " ) ;
2005-05-03 11:33:49 +04:00
d = talloc_realloc ( p1 , d , double , 0x20000000 ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , ! d , " failed: integer overflow not detected \n " ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( p1 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " misc " , root , 1 ) ;
2005-05-03 11:33:49 +04:00
p1 = talloc_named ( root , 100 , " %d bytes " , 100 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " misc " , p1 , 2 ) ;
CHECK_BLOCKS ( " misc " , root , 3 ) ;
2005-05-03 11:33:49 +04:00
talloc_unlink ( root , p1 ) ;
p1 = talloc_init ( " %d bytes " , 200 ) ;
p2 = talloc_asprintf ( p1 , " my test '%s' " , " string " ) ;
2006-10-21 04:23:27 +04:00
torture_assert_str_equal ( " misc " , p2 , " my test 'string' " ,
" failed: talloc_asprintf( \" my test '%%s' \" , \" string \" ) gave: \" %s \" " ) ;
CHECK_BLOCKS ( " misc " , p1 , 3 ) ;
CHECK_SIZE ( " misc " , p2 , 17 ) ;
CHECK_BLOCKS ( " misc " , root , 1 ) ;
2005-05-03 11:33:49 +04:00
talloc_unlink ( NULL , p1 ) ;
p1 = talloc_named_const ( root , 10 , " p1 " ) ;
2006-08-17 15:54:23 +04:00
p2 = ( char * ) talloc_named_const ( root , 20 , " p2 " ) ;
2006-08-31 11:42:47 +04:00
( void ) talloc_reference ( p1 , p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
talloc_unlink ( root , p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
CHECK_BLOCKS ( " misc " , p2 , 1 ) ;
CHECK_BLOCKS ( " misc " , p1 , 2 ) ;
CHECK_BLOCKS ( " misc " , root , 3 ) ;
2005-05-03 11:33:49 +04:00
talloc_unlink ( p1 , p2 ) ;
talloc_unlink ( root , p1 ) ;
2001-12-19 07:46:35 +03:00
2005-05-03 11:33:49 +04:00
p1 = talloc_named_const ( root , 10 , " p1 " ) ;
2006-08-17 15:54:23 +04:00
p2 = ( char * ) talloc_named_const ( root , 20 , " p2 " ) ;
2006-08-31 11:42:47 +04:00
( void ) talloc_reference ( NULL , p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
2005-05-03 11:33:49 +04:00
talloc_unlink ( root , p2 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( root , stderr ) ;
CHECK_BLOCKS ( " misc " , p2 , 1 ) ;
CHECK_BLOCKS ( " misc " , p1 , 1 ) ;
CHECK_BLOCKS ( " misc " , root , 2 ) ;
2005-05-03 11:33:49 +04:00
talloc_unlink ( NULL , p2 ) ;
talloc_unlink ( root , p1 ) ;
2002-01-03 08:57:02 +03:00
2005-05-03 11:33:49 +04:00
/* Test that talloc_unlink is a no-op */
2001-12-19 10:36:32 +03:00
2006-10-21 04:23:27 +04:00
torture_assert ( " misc " , talloc_unlink ( root , NULL ) = = - 1 ,
" failed: talloc_unlink(root, NULL) == -1 \n " ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
talloc_report ( root , stderr ) ;
talloc_report ( NULL , stderr ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " misc " , root , 0 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " misc " , NULL , 0 ) ;
2005-05-03 11:33:49 +04:00
2009-09-21 00:14:40 +04:00
talloc_enable_null_tracking_no_autofree ( ) ;
2005-05-03 11:33:49 +04:00
talloc_enable_leak_report ( ) ;
talloc_enable_leak_report_full ( ) ;
2006-10-21 04:23:27 +04:00
printf ( " success: misc \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
/*
test realloc
*/
2006-09-22 08:16:58 +04:00
static bool test_realloc ( void )
2005-05-03 11:33:49 +04:00
{
void * root , * p1 , * p2 ;
2007-09-19 18:44:16 +04:00
printf ( " test: realloc \n # REALLOC \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_new ( NULL ) ;
p1 = talloc_size ( root , 10 ) ;
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " realloc " , p1 , 10 ) ;
2005-05-03 11:33:49 +04:00
p1 = talloc_realloc_size ( NULL , p1 , 20 ) ;
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " realloc " , p1 , 20 ) ;
2005-05-03 11:33:49 +04:00
talloc_new ( p1 ) ;
p2 = talloc_realloc_size ( p1 , NULL , 30 ) ;
talloc_new ( p1 ) ;
p2 = talloc_realloc_size ( p1 , p2 , 40 ) ;
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " realloc " , p2 , 40 ) ;
CHECK_SIZE ( " realloc " , root , 60 ) ;
CHECK_BLOCKS ( " realloc " , p1 , 4 ) ;
2005-05-03 11:33:49 +04:00
p1 = talloc_realloc_size ( NULL , p1 , 20 ) ;
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " realloc " , p1 , 60 ) ;
2005-05-03 11:33:49 +04:00
talloc_increase_ref_count ( p2 ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " realloc " , talloc_realloc_size ( NULL , p2 , 5 ) = = NULL ,
" failed: talloc_realloc() on a referenced pointer should fail \n " ) ;
CHECK_BLOCKS ( " realloc " , p1 , 4 ) ;
2005-05-03 11:33:49 +04:00
talloc_realloc_size ( NULL , p2 , 0 ) ;
talloc_realloc_size ( NULL , p2 , 0 ) ;
2009-07-01 10:36:29 +04:00
CHECK_BLOCKS ( " realloc " , p1 , 4 ) ;
talloc_realloc_size ( p1 , p2 , 0 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " realloc " , p1 , 3 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
torture_assert ( " realloc " , talloc_realloc_size ( NULL , p1 , 0x7fffffff ) = = NULL ,
" failed: oversize talloc should fail \n " ) ;
2005-05-03 11:33:49 +04:00
talloc_realloc_size ( NULL , p1 , 0 ) ;
2009-07-01 10:36:29 +04:00
CHECK_BLOCKS ( " realloc " , root , 4 ) ;
talloc_realloc_size ( root , p1 , 0 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " realloc " , root , 1 ) ;
2009-07-01 10:36:29 +04:00
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " realloc " , root , 0 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2005-05-03 11:33:49 +04:00
2007-09-19 18:44:16 +04:00
printf ( " success: realloc \n " ) ;
2006-10-21 04:23:27 +04:00
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
/*
test realloc with a child
*/
2006-09-22 08:16:58 +04:00
static bool test_realloc_child ( void )
2005-05-03 11:33:49 +04:00
{
void * root ;
2006-09-05 19:28:28 +04:00
struct el2 {
const char * name ;
2016-11-24 03:57:54 +03:00
} * el2 , * el2_2 , * el2_3 , * * el_list_save ;
2006-09-05 19:28:28 +04:00
struct el1 {
int count ;
struct el2 * * list , * * list2 , * * list3 ;
} * el1 ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
printf ( " test: REALLOC WITH CHILD \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_new ( NULL ) ;
el1 = talloc ( root , struct el1 ) ;
el1 - > list = talloc ( el1 , struct el2 * ) ;
el1 - > list [ 0 ] = talloc ( el1 - > list , struct el2 ) ;
el1 - > list [ 0 ] - > name = talloc_strdup ( el1 - > list [ 0 ] , " testing " ) ;
el1 - > list2 = talloc ( el1 , struct el2 * ) ;
el1 - > list2 [ 0 ] = talloc ( el1 - > list2 , struct el2 ) ;
el1 - > list2 [ 0 ] - > name = talloc_strdup ( el1 - > list2 [ 0 ] , " testing2 " ) ;
el1 - > list3 = talloc ( el1 , struct el2 * ) ;
el1 - > list3 [ 0 ] = talloc ( el1 - > list3 , struct el2 ) ;
el1 - > list3 [ 0 ] - > name = talloc_strdup ( el1 - > list3 [ 0 ] , " testing2 " ) ;
el2 = talloc ( el1 - > list , struct el2 ) ;
2016-11-28 01:47:41 +03:00
CHECK_PARENT ( " el2 " , el2 , el1 - > list ) ;
el2_2 = talloc ( el1 - > list2 , struct el2 ) ;
CHECK_PARENT ( " el2 " , el2_2 , el1 - > list2 ) ;
el2_3 = talloc ( el1 - > list3 , struct el2 ) ;
CHECK_PARENT ( " el2 " , el2_3 , el1 - > list3 ) ;
2005-05-03 11:33:49 +04:00
2016-11-24 03:57:54 +03:00
el_list_save = el1 - > list ;
2005-05-03 11:33:49 +04:00
el1 - > list = talloc_realloc ( el1 , el1 - > list , struct el2 * , 100 ) ;
2016-11-24 03:57:54 +03:00
if ( el1 - > list = = el_list_save ) {
printf ( " failure: talloc_realloc didn't move pointer " ) ;
return false ;
}
2016-11-28 01:47:41 +03:00
CHECK_PARENT ( " el1_after_realloc " , el1 - > list , el1 ) ;
2005-05-03 11:33:49 +04:00
el1 - > list2 = talloc_realloc ( el1 , el1 - > list2 , struct el2 * , 200 ) ;
2016-11-28 01:47:41 +03:00
CHECK_PARENT ( " el1_after_realloc " , el1 - > list2 , el1 ) ;
2005-05-03 11:33:49 +04:00
el1 - > list3 = talloc_realloc ( el1 , el1 - > list3 , struct el2 * , 300 ) ;
2016-11-28 01:47:41 +03:00
CHECK_PARENT ( " el1_after_realloc " , el1 - > list3 , el1 ) ;
CHECK_PARENT ( " el2 " , el2 , el1 - > list ) ;
CHECK_PARENT ( " el2 " , el2_2 , el1 - > list2 ) ;
CHECK_PARENT ( " el2 " , el2_3 , el1 - > list3 ) ;
2005-05-03 11:33:49 +04:00
2016-11-24 03:57:54 +03:00
/* Finally check realloc with multiple children */
el1 = talloc_realloc ( root , el1 , struct el1 , 100 ) ;
CHECK_PARENT ( " el1->list " , el1 - > list , el1 ) ;
CHECK_PARENT ( " el1->list2 " , el1 - > list2 , el1 ) ;
CHECK_PARENT ( " el1->list3 " , el1 - > list3 , el1 ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
printf ( " success: REALLOC WITH CHILD \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
/*
test type checking
*/
2006-09-22 08:16:58 +04:00
static bool test_type ( void )
2005-05-03 11:33:49 +04:00
{
void * root ;
struct el1 {
int count ;
} ;
struct el2 {
int count ;
} ;
struct el1 * el1 ;
2007-09-19 18:44:16 +04:00
printf ( " test: type \n # talloc type checking \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_new ( NULL ) ;
el1 = talloc ( root , struct el1 ) ;
el1 - > count = 1 ;
2006-10-21 04:23:27 +04:00
torture_assert ( " type " , talloc_get_type ( el1 , struct el1 ) = = el1 ,
" type check failed on el1 \n " ) ;
torture_assert ( " type " , talloc_get_type ( el1 , struct el2 ) = = NULL ,
" type check failed on el1 with el2 \n " ) ;
2005-05-03 11:33:49 +04:00
talloc_set_type ( el1 , struct el2 ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " type " , talloc_get_type ( el1 , struct el2 ) = = ( struct el2 * ) el1 ,
" type set failed on el1 with el2 \n " ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
printf ( " success: type \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
/*
test steal
*/
2006-09-22 08:16:58 +04:00
static bool test_steal ( void )
2005-05-03 11:33:49 +04:00
{
void * root , * p1 , * p2 ;
2007-09-19 18:44:16 +04:00
printf ( " test: steal \n # STEAL \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_new ( NULL ) ;
p1 = talloc_array ( root , char , 10 ) ;
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " steal " , p1 , 10 ) ;
2005-05-03 11:33:49 +04:00
p2 = talloc_realloc ( root , NULL , char , 20 ) ;
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " steal " , p1 , 10 ) ;
CHECK_SIZE ( " steal " , root , 30 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
torture_assert ( " steal " , talloc_steal ( p1 , NULL ) = = NULL ,
" failed: stealing NULL should give NULL \n " ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
torture_assert ( " steal " , talloc_steal ( p1 , p1 ) = = p1 ,
" failed: stealing to ourselves is a nop \n " ) ;
CHECK_BLOCKS ( " steal " , root , 3 ) ;
CHECK_SIZE ( " steal " , root , 30 ) ;
2005-05-03 11:33:49 +04:00
talloc_steal ( NULL , p1 ) ;
talloc_steal ( NULL , p2 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " steal " , root , 1 ) ;
CHECK_SIZE ( " steal " , root , 0 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( p1 ) ;
2005-05-03 11:33:49 +04:00
talloc_steal ( root , p2 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " steal " , root , 2 ) ;
CHECK_SIZE ( " steal " , root , 20 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( p2 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " steal " , root , 1 ) ;
CHECK_SIZE ( " steal " , root , 0 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2005-05-03 11:33:49 +04:00
p1 = talloc_size ( NULL , 3 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( NULL , stderr ) ;
CHECK_SIZE ( " steal " , NULL , 3 ) ;
2006-02-20 21:55:15 +03:00
talloc_free ( p1 ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
printf ( " success: steal \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
}
/*
test move
*/
static bool test_move ( void )
{
void * root ;
struct t_move {
char * p ;
int * x ;
} * t1 , * t2 ;
2006-10-21 04:23:27 +04:00
2007-09-19 18:44:16 +04:00
printf ( " test: move \n # MOVE \n " ) ;
2006-09-22 08:16:58 +04:00
root = talloc_new ( NULL ) ;
t1 = talloc ( root , struct t_move ) ;
t2 = talloc ( root , struct t_move ) ;
t1 - > p = talloc_strdup ( t1 , " foo " ) ;
t1 - > x = talloc ( t1 , int ) ;
* t1 - > x = 42 ;
t2 - > p = talloc_move ( t2 , & t1 - > p ) ;
t2 - > x = talloc_move ( t2 , & t1 - > x ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " move " , t1 - > p = = NULL & & t1 - > x = = NULL & &
strcmp ( t2 - > p , " foo " ) = = 0 & & * t2 - > x = = 42 ,
" talloc move failed " ) ;
2006-09-22 08:16:58 +04:00
talloc_free ( root ) ;
2006-10-21 04:23:27 +04:00
printf ( " success: move \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
/*
test talloc_realloc_fn
*/
2006-09-22 08:16:58 +04:00
static bool test_realloc_fn ( void )
2005-05-03 11:33:49 +04:00
{
void * root , * p1 ;
2007-09-19 18:44:16 +04:00
printf ( " test: realloc_fn \n # talloc_realloc_fn \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_new ( NULL ) ;
p1 = talloc_realloc_fn ( root , NULL , 10 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " realloc_fn " , root , 2 ) ;
CHECK_SIZE ( " realloc_fn " , root , 10 ) ;
2005-05-03 11:33:49 +04:00
p1 = talloc_realloc_fn ( root , p1 , 20 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " realloc_fn " , root , 2 ) ;
CHECK_SIZE ( " realloc_fn " , root , 20 ) ;
2005-05-03 11:33:49 +04:00
p1 = talloc_realloc_fn ( root , p1 , 0 ) ;
2006-10-21 04:23:27 +04:00
CHECK_BLOCKS ( " realloc_fn " , root , 1 ) ;
CHECK_SIZE ( " realloc_fn " , root , 0 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( root ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
printf ( " success: realloc_fn \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
2006-09-22 08:16:58 +04:00
static bool test_unref_reparent ( void )
2005-05-03 11:33:49 +04:00
{
void * root , * p1 , * p2 , * c1 ;
2007-09-19 18:44:16 +04:00
printf ( " test: unref_reparent \n # UNREFERENCE AFTER PARENT FREED \n " ) ;
2005-05-03 11:33:49 +04:00
root = talloc_named_const ( NULL , 0 , " root " ) ;
p1 = talloc_named_const ( root , 1 , " orig parent " ) ;
p2 = talloc_named_const ( root , 1 , " parent by reference " ) ;
c1 = talloc_named_const ( p1 , 1 , " child " ) ;
talloc_reference ( p2 , c1 ) ;
2006-10-21 04:23:27 +04:00
CHECK_PARENT ( " unref_reparent " , c1 , p1 ) ;
2006-08-31 11:42:47 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( p1 ) ;
2006-08-31 11:42:47 +04:00
2006-10-21 04:23:27 +04:00
CHECK_PARENT ( " unref_reparent " , c1 , p2 ) ;
2006-08-31 11:42:47 +04:00
2005-05-03 11:33:49 +04:00
talloc_unlink ( p2 , c1 ) ;
2006-10-21 04:23:27 +04:00
CHECK_SIZE ( " unref_reparent " , root , 1 ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( p2 ) ;
talloc_free ( root ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
printf ( " success: unref_reparent \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
/*
measure the speed of talloc versus malloc
*/
2006-09-22 08:16:58 +04:00
static bool test_speed ( void )
2005-05-03 11:33:49 +04:00
{
void * ctx = talloc_new ( NULL ) ;
unsigned count ;
2006-10-21 04:23:27 +04:00
const int loop = 1000 ;
int i ;
2005-05-03 11:33:49 +04:00
struct timeval tv ;
2007-09-19 18:44:16 +04:00
printf ( " test: speed \n # TALLOC VS MALLOC SPEED \n " ) ;
2005-05-03 11:33:49 +04:00
2016-06-01 16:42:13 +03:00
tv = private_timeval_current ( ) ;
2005-05-03 11:33:49 +04:00
count = 0 ;
do {
void * p1 , * p2 , * p3 ;
2006-10-21 04:23:27 +04:00
for ( i = 0 ; i < loop ; i + + ) {
p1 = talloc_size ( ctx , loop % 100 ) ;
p2 = talloc_strdup ( p1 , " foo bar " ) ;
p3 = talloc_size ( p1 , 300 ) ;
2014-02-27 12:28:02 +04:00
( void ) p2 ;
( void ) p3 ;
2006-10-21 04:23:27 +04:00
talloc_free ( p1 ) ;
}
count + = 3 * loop ;
2016-06-01 16:42:13 +03:00
} while ( private_timeval_elapsed ( & tv ) < 5.0 ) ;
2005-05-03 11:33:49 +04:00
2016-06-01 16:42:13 +03:00
fprintf ( stderr , " talloc: %.0f ops/sec \n " , count / private_timeval_elapsed ( & tv ) ) ;
2005-05-03 11:33:49 +04:00
2006-02-20 21:55:15 +03:00
talloc_free ( ctx ) ;
2005-05-03 11:33:49 +04:00
2008-01-05 20:26:54 +03:00
ctx = talloc_pool ( NULL , 1024 ) ;
2016-06-01 16:42:13 +03:00
tv = private_timeval_current ( ) ;
2008-01-05 20:26:54 +03:00
count = 0 ;
do {
void * p1 , * p2 , * p3 ;
for ( i = 0 ; i < loop ; i + + ) {
p1 = talloc_size ( ctx , loop % 100 ) ;
p2 = talloc_strdup ( p1 , " foo bar " ) ;
p3 = talloc_size ( p1 , 300 ) ;
2014-02-27 12:28:02 +04:00
( void ) p2 ;
( void ) p3 ;
2012-07-17 23:23:31 +04:00
talloc_free ( p1 ) ;
2008-01-05 20:26:54 +03:00
}
count + = 3 * loop ;
2016-06-01 16:42:13 +03:00
} while ( private_timeval_elapsed ( & tv ) < 5.0 ) ;
2008-01-05 20:26:54 +03:00
talloc_free ( ctx ) ;
2016-06-01 16:42:13 +03:00
fprintf ( stderr , " talloc_pool: %.0f ops/sec \n " , count / private_timeval_elapsed ( & tv ) ) ;
2008-01-05 20:26:54 +03:00
2016-06-01 16:42:13 +03:00
tv = private_timeval_current ( ) ;
2005-05-03 11:33:49 +04:00
count = 0 ;
do {
void * p1 , * p2 , * p3 ;
2006-10-21 04:23:27 +04:00
for ( i = 0 ; i < loop ; i + + ) {
p1 = malloc ( loop % 100 ) ;
p2 = strdup ( " foo bar " ) ;
p3 = malloc ( 300 ) ;
free ( p1 ) ;
free ( p2 ) ;
free ( p3 ) ;
}
count + = 3 * loop ;
2016-06-01 16:42:13 +03:00
} while ( private_timeval_elapsed ( & tv ) < 5.0 ) ;
fprintf ( stderr , " malloc: %.0f ops/sec \n " , count / private_timeval_elapsed ( & tv ) ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
printf ( " success: speed \n " ) ;
2005-05-03 11:33:49 +04:00
2006-10-21 04:23:27 +04:00
return true ;
2005-05-03 11:33:49 +04:00
}
2006-09-22 08:16:58 +04:00
static bool test_lifeless ( void )
2006-08-31 11:42:47 +04:00
{
void * top = talloc_new ( NULL ) ;
char * parent , * child ;
void * child_owner = talloc_new ( NULL ) ;
2007-09-19 18:44:16 +04:00
printf ( " test: lifeless \n # TALLOC_UNLINK LOOP \n " ) ;
2006-08-31 11:42:47 +04:00
parent = talloc_strdup ( top , " parent " ) ;
child = talloc_strdup ( parent , " child " ) ;
( void ) talloc_reference ( child , parent ) ;
( void ) talloc_reference ( child_owner , child ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( top , stderr ) ;
2006-08-31 11:42:47 +04:00
talloc_unlink ( top , parent ) ;
2009-07-01 10:36:29 +04:00
talloc_unlink ( top , child ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( top , stderr ) ;
2006-08-31 11:42:47 +04:00
talloc_free ( top ) ;
talloc_free ( child_owner ) ;
talloc_free ( child ) ;
2006-10-21 04:23:27 +04:00
printf ( " success: lifeless \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2006-08-31 11:42:47 +04:00
}
static int loop_destructor_count ;
static int test_loop_destructor ( char * ptr )
{
loop_destructor_count + + ;
return 0 ;
}
2006-09-22 08:16:58 +04:00
static bool test_loop ( void )
2006-08-31 11:42:47 +04:00
{
void * top = talloc_new ( NULL ) ;
char * parent ;
struct req1 {
char * req2 , * req3 ;
} * req1 ;
2007-09-19 18:44:16 +04:00
printf ( " test: loop \n # TALLOC LOOP DESTRUCTION \n " ) ;
2006-10-21 04:23:27 +04:00
2006-08-31 11:42:47 +04:00
parent = talloc_strdup ( top , " parent " ) ;
req1 = talloc ( parent , struct req1 ) ;
req1 - > req2 = talloc_strdup ( req1 , " req2 " ) ;
talloc_set_destructor ( req1 - > req2 , test_loop_destructor ) ;
req1 - > req3 = talloc_strdup ( req1 , " req3 " ) ;
( void ) talloc_reference ( req1 - > req3 , req1 ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( top , stderr ) ;
2006-08-31 11:42:47 +04:00
talloc_free ( parent ) ;
2006-10-21 04:23:27 +04:00
talloc_report_full ( top , stderr ) ;
talloc_report_full ( NULL , stderr ) ;
2006-08-31 11:42:47 +04:00
talloc_free ( top ) ;
2006-10-21 04:23:27 +04:00
torture_assert ( " loop " , loop_destructor_count = = 1 ,
" FAILED TO FIRE LOOP DESTRUCTOR \n " ) ;
2006-08-31 13:27:03 +04:00
loop_destructor_count = 0 ;
2006-08-31 11:42:47 +04:00
2006-10-21 04:23:27 +04:00
printf ( " success: loop \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2006-08-31 11:42:47 +04:00
}
2016-11-24 03:57:54 +03:00
static int realloc_parent_destructor_count ;
static int test_realloc_parent_destructor ( char * ptr )
{
realloc_parent_destructor_count + + ;
return 0 ;
}
static bool test_realloc_on_destructor_parent ( void )
{
void * top = talloc_new ( NULL ) ;
char * parent ;
char * a , * b , * C , * D ;
realloc_parent_destructor_count = 0 ;
printf ( " test: free_for_exit \n # TALLOC FREE FOR EXIT \n " ) ;
parent = talloc_strdup ( top , " parent " ) ;
a = talloc_strdup ( parent , " a " ) ;
b = talloc_strdup ( a , " b " ) ;
C = talloc_strdup ( a , " C " ) ;
D = talloc_strdup ( b , " D " ) ;
talloc_set_destructor ( D , test_realloc_parent_destructor ) ;
/* Capitalised ones have destructors.
*
* parent - - > a - > b - > D
* - > c
*/
a = talloc_realloc ( parent , a , char , 2048 ) ;
torture_assert ( " check talloc_realloc " , a ! = NULL , " talloc_realloc failed " ) ;
talloc_set_destructor ( C , test_realloc_parent_destructor ) ;
/*
* parent - - > a [ 2048 ] - > b - > D
* - > C
*
*/
talloc_free ( parent ) ;
torture_assert ( " check destructor realloc_parent_destructor " ,
realloc_parent_destructor_count = = 2 ,
" FAILED TO FIRE free_for_exit_destructor \n " ) ;
printf ( " success: free_for_exit \n " ) ;
2019-08-15 15:22:46 +03:00
talloc_free ( top ) ; /* make ASAN happy */
2016-11-24 03:57:54 +03:00
return true ;
}
2006-08-31 11:42:47 +04:00
static int fail_destructor_str ( char * ptr )
{
return - 1 ;
}
2006-09-22 08:16:58 +04:00
static bool test_free_parent_deny_child ( void )
2006-08-31 11:42:47 +04:00
{
void * top = talloc_new ( NULL ) ;
char * level1 ;
char * level2 ;
char * level3 ;
2007-09-19 18:44:16 +04:00
printf ( " test: free_parent_deny_child \n # TALLOC FREE PARENT DENY CHILD \n " ) ;
2006-10-21 04:23:27 +04:00
2006-08-31 11:42:47 +04:00
level1 = talloc_strdup ( top , " level1 " ) ;
level2 = talloc_strdup ( level1 , " level2 " ) ;
level3 = talloc_strdup ( level2 , " level3 " ) ;
talloc_set_destructor ( level3 , fail_destructor_str ) ;
talloc_free ( level1 ) ;
talloc_set_destructor ( level3 , NULL ) ;
2006-10-21 04:23:27 +04:00
CHECK_PARENT ( " free_parent_deny_child " , level3 , top ) ;
2006-08-31 11:42:47 +04:00
talloc_free ( top ) ;
2006-10-21 04:23:27 +04:00
printf ( " success: free_parent_deny_child \n " ) ;
2006-09-22 08:16:58 +04:00
return true ;
2006-08-31 11:42:47 +04:00
}
2015-03-04 04:12:32 +03:00
struct new_parent {
void * new_parent ;
char val [ 20 ] ;
} ;
static int reparenting_destructor ( struct new_parent * np )
{
talloc_set_destructor ( np , NULL ) ;
( void ) talloc_move ( np - > new_parent , & np ) ;
return - 1 ;
}
static bool test_free_parent_reparent_child ( void )
{
void * top = talloc_new ( NULL ) ;
char * level1 ;
char * alternate_level1 ;
char * level2 ;
struct new_parent * level3 ;
printf ( " test: free_parent_reparent_child \n # "
" TALLOC FREE PARENT REPARENT CHILD \n " ) ;
level1 = talloc_strdup ( top , " level1 " ) ;
alternate_level1 = talloc_strdup ( top , " alternate_level1 " ) ;
level2 = talloc_strdup ( level1 , " level2 " ) ;
level3 = talloc ( level2 , struct new_parent ) ;
level3 - > new_parent = alternate_level1 ;
memset ( level3 - > val , ' x ' , sizeof ( level3 - > val ) ) ;
talloc_set_destructor ( level3 , reparenting_destructor ) ;
talloc_free ( level1 ) ;
CHECK_PARENT ( " free_parent_reparent_child " ,
level3 , alternate_level1 ) ;
talloc_free ( top ) ;
printf ( " success: free_parent_reparent_child \n " ) ;
return true ;
}
static bool test_free_parent_reparent_child_in_pool ( void )
{
void * top = talloc_new ( NULL ) ;
char * level1 ;
char * alternate_level1 ;
char * level2 ;
void * pool ;
struct new_parent * level3 ;
printf ( " test: free_parent_reparent_child_in_pool \n # "
" TALLOC FREE PARENT REPARENT CHILD IN POOL \n " ) ;
pool = talloc_pool ( top , 1024 ) ;
level1 = talloc_strdup ( pool , " level1 " ) ;
alternate_level1 = talloc_strdup ( top , " alternate_level1 " ) ;
level2 = talloc_strdup ( level1 , " level2 " ) ;
level3 = talloc ( level2 , struct new_parent ) ;
level3 - > new_parent = alternate_level1 ;
memset ( level3 - > val , ' x ' , sizeof ( level3 - > val ) ) ;
talloc_set_destructor ( level3 , reparenting_destructor ) ;
talloc_free ( level1 ) ;
talloc_set_destructor ( level3 , NULL ) ;
CHECK_PARENT ( " free_parent_reparent_child_in_pool " ,
level3 , alternate_level1 ) ;
/* Even freeing alternate_level1 should leave pool alone. */
talloc_free ( alternate_level1 ) ;
talloc_free ( top ) ;
printf ( " success: free_parent_reparent_child_in_pool \n " ) ;
return true ;
}
2006-09-22 08:16:58 +04:00
static bool test_talloc_ptrtype ( void )
2006-08-31 11:42:47 +04:00
{
void * top = talloc_new ( NULL ) ;
struct struct1 {
int foo ;
int bar ;
} * s1 , * s2 , * * s3 , * * * s4 ;
const char * location1 ;
const char * location2 ;
const char * location3 ;
const char * location4 ;
2007-09-19 18:44:16 +04:00
printf ( " test: ptrtype \n # TALLOC PTRTYPE \n " ) ;
2006-10-21 04:23:27 +04:00
2006-08-31 11:42:47 +04:00
s1 = talloc_ptrtype ( top , s1 ) ; location1 = __location__ ;
if ( talloc_get_size ( s1 ) ! = sizeof ( struct struct1 ) ) {
2006-10-21 04:23:27 +04:00
printf ( " failure: ptrtype [ \n "
" talloc_ptrtype() allocated the wrong size %lu (should be %lu) \n "
" ] \n " , ( unsigned long ) talloc_get_size ( s1 ) ,
( unsigned long ) sizeof ( struct struct1 ) ) ;
return false ;
2006-08-31 11:42:47 +04:00
}
if ( strcmp ( location1 , talloc_get_name ( s1 ) ) ! = 0 ) {
2006-10-21 04:23:27 +04:00
printf ( " failure: ptrtype [ \n "
" talloc_ptrtype() sets the wrong name '%s' (should be '%s') \n ] \n " ,
talloc_get_name ( s1 ) , location1 ) ;
return false ;
2006-08-31 11:42:47 +04:00
}
s2 = talloc_array_ptrtype ( top , s2 , 10 ) ; location2 = __location__ ;
if ( talloc_get_size ( s2 ) ! = ( sizeof ( struct struct1 ) * 10 ) ) {
2006-10-21 04:23:27 +04:00
printf ( " failure: ptrtype [ \n "
" talloc_array_ptrtype() allocated the wrong size "
" %lu (should be %lu) \n ] \n " ,
( unsigned long ) talloc_get_size ( s2 ) ,
( unsigned long ) ( sizeof ( struct struct1 ) * 10 ) ) ;
return false ;
2006-08-31 11:42:47 +04:00
}
if ( strcmp ( location2 , talloc_get_name ( s2 ) ) ! = 0 ) {
2006-10-21 04:23:27 +04:00
printf ( " failure: ptrtype [ \n "
" talloc_array_ptrtype() sets the wrong name '%s' (should be '%s') \n ] \n " ,
talloc_get_name ( s2 ) , location2 ) ;
return false ;
2006-08-31 11:42:47 +04:00
}
s3 = talloc_array_ptrtype ( top , s3 , 10 ) ; location3 = __location__ ;
if ( talloc_get_size ( s3 ) ! = ( sizeof ( struct struct1 * ) * 10 ) ) {
2006-10-21 04:23:27 +04:00
printf ( " failure: ptrtype [ \n "
" talloc_array_ptrtype() allocated the wrong size "
" %lu (should be %lu) \n ] \n " ,
( unsigned long ) talloc_get_size ( s3 ) ,
2006-09-04 12:55:58 +04:00
( unsigned long ) ( sizeof ( struct struct1 * ) * 10 ) ) ;
2006-10-21 04:23:27 +04:00
return false ;
2006-08-31 11:42:47 +04:00
}
2006-10-21 04:23:27 +04:00
torture_assert_str_equal ( " ptrtype " , location3 , talloc_get_name ( s3 ) ,
" talloc_array_ptrtype() sets the wrong name " ) ;
2006-08-31 11:42:47 +04:00
s4 = talloc_array_ptrtype ( top , s4 , 10 ) ; location4 = __location__ ;
if ( talloc_get_size ( s4 ) ! = ( sizeof ( struct struct1 * * ) * 10 ) ) {
2007-05-08 15:12:11 +04:00
printf ( " failure: ptrtype [ \n "
2006-10-21 04:23:27 +04:00
" talloc_array_ptrtype() allocated the wrong size "
" %lu (should be %lu) \n ] \n " ,
( unsigned long ) talloc_get_size ( s4 ) ,
2006-09-04 12:55:58 +04:00
( unsigned long ) ( sizeof ( struct struct1 * * ) * 10 ) ) ;
2006-10-21 04:23:27 +04:00
return false ;
2006-08-31 11:42:47 +04:00
}
2006-10-21 04:23:27 +04:00
torture_assert_str_equal ( " ptrtype " , location4 , talloc_get_name ( s4 ) ,
" talloc_array_ptrtype() sets the wrong name " ) ;
2006-08-31 11:42:47 +04:00
talloc_free ( top ) ;
2006-10-21 04:23:27 +04:00
printf ( " success: ptrtype \n " ) ;
return true ;
2006-08-31 11:42:47 +04:00
}
2007-05-08 15:12:11 +04:00
static int _test_talloc_free_in_destructor ( void * * ptr )
{
talloc_free ( * ptr ) ;
return 0 ;
}
static bool test_talloc_free_in_destructor ( void )
{
void * level0 ;
void * level1 ;
void * level2 ;
void * level3 ;
void * level4 ;
void * * level5 ;
2007-09-19 18:44:16 +04:00
printf ( " test: free_in_destructor \n # TALLOC FREE IN DESTRUCTOR \n " ) ;
2007-05-08 15:12:11 +04:00
level0 = talloc_new ( NULL ) ;
level1 = talloc_new ( level0 ) ;
level2 = talloc_new ( level1 ) ;
level3 = talloc_new ( level2 ) ;
level4 = talloc_new ( level3 ) ;
level5 = talloc ( level4 , void * ) ;
* level5 = level3 ;
( void ) talloc_reference ( level0 , level3 ) ;
( void ) talloc_reference ( level3 , level3 ) ;
( void ) talloc_reference ( level5 , level3 ) ;
talloc_set_destructor ( level5 , _test_talloc_free_in_destructor ) ;
talloc_free ( level1 ) ;
talloc_free ( level0 ) ;
2019-08-15 15:33:32 +03:00
talloc_free ( level3 ) ; /* make ASAN happy */
2007-05-08 15:12:11 +04:00
printf ( " success: free_in_destructor \n " ) ;
return true ;
}
2006-09-29 14:53:27 +04:00
static bool test_autofree ( void )
{
2007-04-19 13:08:53 +04:00
# if _SAMBA_BUILD_ < 4
/* autofree test would kill smbtorture */
2006-09-29 14:53:27 +04:00
void * p ;
2007-09-19 18:44:16 +04:00
printf ( " test: autofree \n # TALLOC AUTOFREE CONTEXT \n " ) ;
2006-09-29 14:53:27 +04:00
p = talloc_autofree_context ( ) ;
talloc_free ( p ) ;
p = talloc_autofree_context ( ) ;
talloc_free ( p ) ;
2006-10-21 04:23:27 +04:00
printf ( " success: autofree \n " ) ;
2007-04-19 13:08:53 +04:00
# endif
2006-09-29 14:53:27 +04:00
return true ;
}
2008-01-05 20:26:54 +03:00
static bool test_pool ( void )
{
void * pool ;
void * p1 , * p2 , * p3 , * p4 ;
2011-03-31 21:50:47 +04:00
void * p2_2 ;
2008-01-05 20:26:54 +03:00
pool = talloc_pool ( NULL , 1024 ) ;
p1 = talloc_size ( pool , 80 ) ;
2011-05-17 10:20:13 +04:00
memset ( p1 , 0x11 , talloc_get_size ( p1 ) ) ;
2008-01-05 20:26:54 +03:00
p2 = talloc_size ( pool , 20 ) ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2008-01-05 20:26:54 +03:00
p3 = talloc_size ( p1 , 50 ) ;
2011-05-17 10:20:13 +04:00
memset ( p3 , 0x11 , talloc_get_size ( p3 ) ) ;
2008-01-05 20:26:54 +03:00
p4 = talloc_size ( p3 , 1000 ) ;
2011-05-17 10:20:13 +04:00
memset ( p4 , 0x11 , talloc_get_size ( p4 ) ) ;
2008-01-05 20:26:54 +03:00
2011-03-31 21:50:47 +04:00
# if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
p2_2 = talloc_realloc_size ( pool , p2 , 20 + 1 ) ;
torture_assert ( " pool realloc 20+1 " , p2_2 = = p2 , " failed: pointer changed " ) ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2011-03-31 21:50:47 +04:00
p2_2 = talloc_realloc_size ( pool , p2 , 20 - 1 ) ;
torture_assert ( " pool realloc 20-1 " , p2_2 = = p2 , " failed: pointer changed " ) ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2011-03-31 21:50:47 +04:00
p2_2 = talloc_realloc_size ( pool , p2 , 20 - 1 ) ;
torture_assert ( " pool realloc 20-1 " , p2_2 = = p2 , " failed: pointer changed " ) ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2011-03-31 21:50:47 +04:00
talloc_free ( p3 ) ;
/* this should reclaim the memory of p4 and p3 */
p2_2 = talloc_realloc_size ( pool , p2 , 400 ) ;
torture_assert ( " pool realloc 400 " , p2_2 = = p2 , " failed: pointer changed " ) ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2011-03-31 21:50:47 +04:00
talloc_free ( p1 ) ;
/* this should reclaim the memory of p1 */
p2_2 = talloc_realloc_size ( pool , p2 , 800 ) ;
torture_assert ( " pool realloc 800 " , p2_2 = = p1 , " failed: pointer not changed " ) ;
p2 = p2_2 ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2011-03-31 21:50:47 +04:00
/* this should do a malloc */
p2_2 = talloc_realloc_size ( pool , p2 , 1800 ) ;
torture_assert ( " pool realloc 1800 " , p2_2 ! = p2 , " failed: pointer not changed " ) ;
p2 = p2_2 ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2011-03-31 21:50:47 +04:00
/* this should reclaim the memory from the pool */
p3 = talloc_size ( pool , 80 ) ;
torture_assert ( " pool alloc 80 " , p3 = = p1 , " failed: pointer changed " ) ;
2011-05-17 10:20:13 +04:00
memset ( p3 , 0x11 , talloc_get_size ( p3 ) ) ;
2011-03-31 21:50:47 +04:00
talloc_free ( p2 ) ;
talloc_free ( p3 ) ;
p1 = talloc_size ( pool , 80 ) ;
2011-05-17 10:20:13 +04:00
memset ( p1 , 0x11 , talloc_get_size ( p1 ) ) ;
2011-03-31 21:50:47 +04:00
p2 = talloc_size ( pool , 20 ) ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2011-03-31 21:50:47 +04:00
talloc_free ( p1 ) ;
p2_2 = talloc_realloc_size ( pool , p2 , 20 - 1 ) ;
torture_assert ( " pool realloc 20-1 " , p2_2 = = p2 , " failed: pointer changed " ) ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2011-03-31 21:50:47 +04:00
p2_2 = talloc_realloc_size ( pool , p2 , 20 - 1 ) ;
torture_assert ( " pool realloc 20-1 " , p2_2 = = p2 , " failed: pointer changed " ) ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2011-03-31 21:50:47 +04:00
/* this should do a malloc */
p2_2 = talloc_realloc_size ( pool , p2 , 1800 ) ;
torture_assert ( " pool realloc 1800 " , p2_2 ! = p2 , " failed: pointer not changed " ) ;
p2 = p2_2 ;
2011-05-17 10:20:13 +04:00
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
2011-03-31 21:50:47 +04:00
/* this should reclaim the memory from the pool */
p3 = talloc_size ( pool , 800 ) ;
torture_assert ( " pool alloc 800 " , p3 = = p1 , " failed: pointer changed " ) ;
2011-05-17 10:20:13 +04:00
memset ( p3 , 0x11 , talloc_get_size ( p3 ) ) ;
2011-03-31 21:50:47 +04:00
# endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
2008-01-05 20:26:54 +03:00
talloc_free ( pool ) ;
return true ;
}
2011-05-16 21:25:47 +04:00
static bool test_pool_steal ( void )
{
void * root ;
void * pool ;
void * p1 , * p2 ;
void * p1_2 , * p2_2 ;
size_t hdr ;
size_t ofs1 , ofs2 ;
root = talloc_new ( NULL ) ;
pool = talloc_pool ( root , 1024 ) ;
p1 = talloc_size ( pool , 4 * 16 ) ;
torture_assert ( " pool allocate 4 * 16 " , p1 ! = NULL , " failed " ) ;
memset ( p1 , 0x11 , talloc_get_size ( p1 ) ) ;
p2 = talloc_size ( pool , 4 * 16 ) ;
torture_assert ( " pool allocate 4 * 16 " , p2 > p1 , " failed: !(p2 > p1) " ) ;
memset ( p2 , 0x11 , talloc_get_size ( p2 ) ) ;
ofs1 = PTR_DIFF ( p2 , p1 ) ;
hdr = ofs1 - talloc_get_size ( p1 ) ;
talloc_steal ( root , p1 ) ;
talloc_steal ( root , p2 ) ;
talloc_free ( pool ) ;
p1_2 = p1 ;
# if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
p1_2 = talloc_realloc_size ( root , p1 , 5 * 16 ) ;
torture_assert ( " pool realloc 5 * 16 " , p1_2 > p2 , " failed: pointer not changed " ) ;
memset ( p1_2 , 0x11 , talloc_get_size ( p1_2 ) ) ;
ofs1 = PTR_DIFF ( p1_2 , p2 ) ;
ofs2 = talloc_get_size ( p2 ) + hdr ;
torture_assert ( " pool realloc " , ofs1 = = ofs2 , " failed: pointer offset unexpected " ) ;
p2_2 = talloc_realloc_size ( root , p2 , 3 * 16 ) ;
torture_assert ( " pool realloc 5 * 16 " , p2_2 = = p2 , " failed: pointer changed " ) ;
memset ( p2_2 , 0x11 , talloc_get_size ( p2_2 ) ) ;
# endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
talloc_free ( p1_2 ) ;
p2_2 = p2 ;
# if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
/* now we should reclaim the full pool */
p2_2 = talloc_realloc_size ( root , p2 , 8 * 16 ) ;
torture_assert ( " pool realloc 8 * 16 " , p2_2 = = p1 , " failed: pointer not expected " ) ;
p2 = p2_2 ;
memset ( p2_2 , 0x11 , talloc_get_size ( p2_2 ) ) ;
/* now we malloc and free the full pool space */
p2_2 = talloc_realloc_size ( root , p2 , 2 * 1024 ) ;
torture_assert ( " pool realloc 2 * 1024 " , p2_2 ! = p1 , " failed: pointer not expected " ) ;
memset ( p2_2 , 0x11 , talloc_get_size ( p2_2 ) ) ;
# endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
talloc_free ( p2_2 ) ;
talloc_free ( root ) ;
return true ;
}
2010-04-20 09:30:57 +04:00
2013-09-07 01:52:28 +04:00
static bool test_pool_nest ( void )
{
void * p1 , * p2 , * p3 ;
void * e = talloc_new ( NULL ) ;
p1 = talloc_pool ( NULL , 1024 ) ;
torture_assert ( " talloc_pool " , p1 ! = NULL , " failed " ) ;
p2 = talloc_pool ( p1 , 500 ) ;
torture_assert ( " talloc_pool " , p2 ! = NULL , " failed " ) ;
p3 = talloc_size ( p2 , 10 ) ;
talloc_steal ( e , p3 ) ;
talloc_free ( p2 ) ;
talloc_free ( p3 ) ;
talloc_free ( p1 ) ;
2019-08-15 15:36:59 +03:00
talloc_free ( e ) ; /* make ASAN happy */
2013-09-07 01:52:28 +04:00
return true ;
}
2013-09-07 02:30:38 +04:00
struct pooled {
char * s1 ;
char * s2 ;
char * s3 ;
} ;
static bool test_pooled_object ( void )
{
struct pooled * p ;
const char * s1 = " hello " ;
const char * s2 = " world " ;
const char * s3 = " " ;
p = talloc_pooled_object ( NULL , struct pooled , 3 ,
strlen ( s1 ) + strlen ( s2 ) + strlen ( s3 ) + 3 ) ;
if ( talloc_get_size ( p ) ! = sizeof ( struct pooled ) ) {
return false ;
}
p - > s1 = talloc_strdup ( p , s1 ) ;
TALLOC_FREE ( p - > s1 ) ;
p - > s1 = talloc_strdup ( p , s2 ) ;
TALLOC_FREE ( p - > s1 ) ;
p - > s1 = talloc_strdup ( p , s1 ) ;
p - > s2 = talloc_strdup ( p , s2 ) ;
p - > s3 = talloc_strdup ( p , s3 ) ;
TALLOC_FREE ( p ) ;
return true ;
}
2010-04-20 09:30:57 +04:00
static bool test_free_ref_null_context ( void )
{
void * p1 , * p2 , * p3 ;
int ret ;
talloc_disable_null_tracking ( ) ;
p1 = talloc_new ( NULL ) ;
p2 = talloc_new ( NULL ) ;
p3 = talloc_reference ( p2 , p1 ) ;
torture_assert ( " reference " , p3 = = p1 , " failed: reference on null " ) ;
ret = talloc_free ( p1 ) ;
torture_assert ( " ref free with null parent " , ret = = 0 , " failed: free with null parent " ) ;
talloc_free ( p2 ) ;
talloc_enable_null_tracking_no_autofree ( ) ;
p1 = talloc_new ( NULL ) ;
p2 = talloc_new ( NULL ) ;
p3 = talloc_reference ( p2 , p1 ) ;
torture_assert ( " reference " , p3 = = p1 , " failed: reference on null " ) ;
ret = talloc_free ( p1 ) ;
torture_assert ( " ref free with null tracked parent " , ret = = 0 , " failed: free with null parent " ) ;
talloc_free ( p2 ) ;
return true ;
}
2010-12-22 07:29:37 +03:00
static bool test_rusty ( void )
{
void * root ;
2019-08-15 15:39:58 +03:00
char * p1 ;
2010-12-22 07:29:37 +03:00
talloc_enable_null_tracking ( ) ;
root = talloc_new ( NULL ) ;
p1 = talloc_strdup ( root , " foo " ) ;
talloc_increase_ref_count ( p1 ) ;
talloc_report_full ( root , stdout ) ;
talloc_free ( root ) ;
2011-08-04 06:07:19 +04:00
CHECK_BLOCKS ( " null_context " , NULL , 2 ) ;
2019-08-15 15:39:58 +03:00
talloc_free ( p1 ) ; /* make ASAN happy */
2010-12-22 07:29:37 +03:00
return true ;
}
2011-07-29 05:57:07 +04:00
static bool test_free_children ( void )
{
void * root ;
2012-01-04 15:57:10 +04:00
char * p1 , * p2 ;
const char * name , * name2 ;
2011-07-29 05:57:07 +04:00
talloc_enable_null_tracking ( ) ;
root = talloc_new ( NULL ) ;
p1 = talloc_strdup ( root , " foo1 " ) ;
p2 = talloc_strdup ( p1 , " foo2 " ) ;
2014-02-27 12:28:02 +04:00
( void ) p2 ;
2011-07-29 05:57:07 +04:00
talloc_set_name ( p1 , " %s " , " testname " ) ;
talloc_free_children ( p1 ) ;
/* check its still a valid talloc ptr */
talloc_get_size ( talloc_get_name ( p1 ) ) ;
if ( strcmp ( talloc_get_name ( p1 ) , " testname " ) ! = 0 ) {
return false ;
}
talloc_set_name ( p1 , " %s " , " testname " ) ;
name = talloc_get_name ( p1 ) ;
talloc_free_children ( p1 ) ;
/* check its still a valid talloc ptr */
talloc_get_size ( talloc_get_name ( p1 ) ) ;
torture_assert ( " name " , name = = talloc_get_name ( p1 ) , " name ptr changed " ) ;
torture_assert ( " namecheck " , strcmp ( talloc_get_name ( p1 ) , " testname " ) = = 0 ,
" wrong name " ) ;
CHECK_BLOCKS ( " name1 " , p1 , 2 ) ;
/* note that this does not free the old child name */
talloc_set_name_const ( p1 , " testname2 " ) ;
name2 = talloc_get_name ( p1 ) ;
/* but this does */
talloc_free_children ( p1 ) ;
2014-02-27 12:28:02 +04:00
( void ) name2 ;
2011-07-29 05:57:07 +04:00
torture_assert ( " namecheck " , strcmp ( talloc_get_name ( p1 ) , " testname2 " ) = = 0 ,
" wrong name " ) ;
CHECK_BLOCKS ( " name1 " , p1 , 1 ) ;
talloc_report_full ( root , stdout ) ;
talloc_free ( root ) ;
return true ;
}
2012-09-23 00:35:21 +04:00
static bool test_memlimit ( void )
{
void * root ;
char * l1 , * l2 , * l3 , * l4 , * l5 , * t ;
2013-08-28 00:09:03 +04:00
char * pool ;
int i ;
2012-09-23 00:35:21 +04:00
printf ( " test: memlimit \n # MEMORY LIMITS \n " ) ;
printf ( " ==== talloc_new(NULL) \n " ) ;
root = talloc_new ( NULL ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_size(root, 2048) \n " ) ;
l1 = talloc_size ( root , 2048 ) ;
torture_assert ( " memlimit " , l1 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_free(l1) \n " ) ;
talloc_free ( l1 ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_strdup(root, level 1) \n " ) ;
l1 = talloc_strdup ( root , " level 1 " ) ;
torture_assert ( " memlimit " , l1 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_set_memlimit(l1, 2048) \n " ) ;
torture_assert ( " memlimit " , talloc_set_memlimit ( l1 , 2048 ) = = 0 ,
" failed: setting memlimit should never fail \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_size(root, 2048) \n " ) ;
l2 = talloc_size ( l1 , 2048 ) ;
torture_assert ( " memlimit " , l2 = = NULL ,
" failed: alloc should fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_strdup(l1, level 2) \n " ) ;
l2 = talloc_strdup ( l1 , " level 2 " ) ;
torture_assert ( " memlimit " , l2 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_free(l2) \n " ) ;
talloc_free ( l2 ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_size(NULL, 2048) \n " ) ;
l2 = talloc_size ( NULL , 2048 ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_steal(l1, l2) \n " ) ;
talloc_steal ( l1 , l2 ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_strdup(l2, level 3) \n " ) ;
l3 = talloc_strdup ( l2 , " level 3 " ) ;
torture_assert ( " memlimit " , l3 = = NULL ,
" failed: alloc should fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_free(l2) \n " ) ;
talloc_free ( l2 ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_strdup(NULL, level 2) \n " ) ;
l2 = talloc_strdup ( NULL , " level 2 " ) ;
talloc_steal ( l1 , l2 ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_strdup(l2, level 3) \n " ) ;
l3 = talloc_strdup ( l2 , " level 3 " ) ;
torture_assert ( " memlimit " , l3 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_set_memlimit(l3, 1024) \n " ) ;
torture_assert ( " memlimit " , talloc_set_memlimit ( l3 , 1024 ) = = 0 ,
" failed: setting memlimit should never fail \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_strdup(l3, level 4) \n " ) ;
l4 = talloc_strdup ( l3 , " level 4 " ) ;
torture_assert ( " memlimit " , l4 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_set_memlimit(l4, 512) \n " ) ;
torture_assert ( " memlimit " , talloc_set_memlimit ( l4 , 512 ) = = 0 ,
" failed: setting memlimit should never fail \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_strdup(l4, level 5) \n " ) ;
l5 = talloc_strdup ( l4 , " level 5 " ) ;
torture_assert ( " memlimit " , l5 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_realloc(NULL, l5, char, 600) \n " ) ;
t = talloc_realloc ( NULL , l5 , char , 600 ) ;
torture_assert ( " memlimit " , t = = NULL ,
" failed: alloc should fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_realloc(NULL, l5, char, 5) \n " ) ;
l5 = talloc_realloc ( NULL , l5 , char , 5 ) ;
torture_assert ( " memlimit " , l5 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_strdup(l3, level 4) \n " ) ;
l4 = talloc_strdup ( l3 , " level 4 " ) ;
torture_assert ( " memlimit " , l4 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_set_memlimit(l4, 512) \n " ) ;
torture_assert ( " memlimit " , talloc_set_memlimit ( l4 , 512 ) = = 0 ,
" failed: setting memlimit should never fail \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_strdup(l4, level 5) \n " ) ;
l5 = talloc_strdup ( l4 , " level 5 " ) ;
torture_assert ( " memlimit " , l5 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== Make new temp context and steal l5 \n " ) ;
t = talloc_new ( root ) ;
talloc_steal ( t , l5 ) ;
talloc_report_full ( root , stdout ) ;
printf ( " ==== talloc_size(t, 2048) \n " ) ;
l1 = talloc_size ( t , 2048 ) ;
torture_assert ( " memlimit " , l1 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_report_full ( root , stdout ) ;
talloc_free ( root ) ;
2013-08-28 00:09:03 +04:00
/* Test memlimits with pools. */
pool = talloc_pool ( NULL , 10 * 1024 ) ;
torture_assert ( " memlimit " , pool ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
talloc_set_memlimit ( pool , 10 * 1024 ) ;
for ( i = 0 ; i < 9 ; i + + ) {
l1 = talloc_size ( pool , 1024 ) ;
torture_assert ( " memlimit " , l1 ! = NULL ,
" failed: alloc should not fail due to memory limit \n " ) ;
}
/* The next alloc should fail. */
l2 = talloc_size ( pool , 1024 ) ;
torture_assert ( " memlimit " , l2 = = NULL ,
" failed: alloc should fail due to memory limit \n " ) ;
/* Moving one of the children shouldn't change the limit,
as it ' s still inside the pool . */
root = talloc_new ( NULL ) ;
talloc_steal ( root , l1 ) ;
l2 = talloc_size ( pool , 1024 ) ;
torture_assert ( " memlimit " , l2 = = NULL ,
" failed: alloc should fail due to memory limit \n " ) ;
talloc_free ( pool ) ;
talloc_free ( root ) ;
2012-09-23 00:35:21 +04:00
printf ( " success: memlimit \n " ) ;
return true ;
}
2010-12-22 07:29:37 +03:00
2015-03-16 22:18:17 +03:00
# ifdef HAVE_PTHREAD
# define NUM_THREADS 100
/* Sync variables. */
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER ;
static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER ;
static void * intermediate_ptr ;
/* Subthread. */
static void * thread_fn ( void * arg )
{
int ret ;
const char * ctx_name = ( const char * ) arg ;
void * sub_ctx = NULL ;
/*
* Do stuff that creates a new talloc hierarchy in
* this thread .
*/
void * top_ctx = talloc_named_const ( NULL , 0 , " top " ) ;
if ( top_ctx = = NULL ) {
return NULL ;
}
sub_ctx = talloc_named_const ( top_ctx , 100 , ctx_name ) ;
if ( sub_ctx = = NULL ) {
return NULL ;
}
/*
* Now transfer a pointer from our hierarchy
* onto the intermediate ptr .
*/
ret = pthread_mutex_lock ( & mtx ) ;
if ( ret ! = 0 ) {
talloc_free ( top_ctx ) ;
return NULL ;
}
/* Wait for intermediate_ptr to be free. */
while ( intermediate_ptr ! = NULL ) {
ret = pthread_cond_wait ( & condvar , & mtx ) ;
if ( ret ! = 0 ) {
talloc_free ( top_ctx ) ;
2016-10-12 13:18:11 +03:00
ret = pthread_mutex_unlock ( & mtx ) ;
assert ( ret = = 0 ) ;
2015-03-16 22:18:17 +03:00
return NULL ;
}
}
/* and move our memory onto it from our toplevel hierarchy. */
intermediate_ptr = talloc_move ( NULL , & sub_ctx ) ;
/* Tell the main thread it's ready for pickup. */
pthread_cond_broadcast ( & condvar ) ;
2016-10-12 13:18:11 +03:00
ret = pthread_mutex_unlock ( & mtx ) ;
assert ( ret = = 0 ) ;
2015-03-16 22:18:17 +03:00
talloc_free ( top_ctx ) ;
return NULL ;
}
/* Main thread. */
static bool test_pthread_talloc_passing ( void )
{
int i ;
int ret ;
char str_array [ NUM_THREADS ] [ 20 ] ;
pthread_t thread_id ;
void * mem_ctx ;
/*
* Important ! Null tracking breaks threaded talloc .
* It * must * be turned off .
*/
talloc_disable_null_tracking ( ) ;
printf ( " test: pthread_talloc_passing \n # PTHREAD TALLOC PASSING \n " ) ;
/* Main thread toplevel context. */
mem_ctx = talloc_named_const ( NULL , 0 , " toplevel " ) ;
if ( mem_ctx = = NULL ) {
printf ( " failed to create toplevel context \n " ) ;
return false ;
}
/*
* Spin off NUM_THREADS threads .
* They will use their own toplevel contexts .
*/
for ( i = 0 ; i < NUM_THREADS ; i + + ) {
2016-04-26 14:02:01 +03:00
ret = snprintf ( str_array [ i ] ,
20 ,
" thread:%d " ,
i ) ;
if ( ret < 0 ) {
2015-03-16 22:18:17 +03:00
printf ( " snprintf %d failed \n " , i ) ;
return false ;
}
ret = pthread_create ( & thread_id ,
NULL ,
thread_fn ,
str_array [ i ] ) ;
if ( ret ! = 0 ) {
printf ( " failed to create thread %d (%d) \n " , i , ret ) ;
return false ;
}
}
printf ( " Created %d threads \n " , NUM_THREADS ) ;
/* Now wait for NUM_THREADS transfers of the talloc'ed memory. */
for ( i = 0 ; i < NUM_THREADS ; i + + ) {
ret = pthread_mutex_lock ( & mtx ) ;
if ( ret ! = 0 ) {
printf ( " pthread_mutex_lock %d failed (%d) \n " , i , ret ) ;
talloc_free ( mem_ctx ) ;
return false ;
}
/* Wait for intermediate_ptr to have our data. */
while ( intermediate_ptr = = NULL ) {
ret = pthread_cond_wait ( & condvar , & mtx ) ;
if ( ret ! = 0 ) {
printf ( " pthread_cond_wait %d failed (%d) \n " , i ,
ret ) ;
talloc_free ( mem_ctx ) ;
2016-10-12 13:27:56 +03:00
ret = pthread_mutex_unlock ( & mtx ) ;
assert ( ret = = 0 ) ;
2015-03-16 22:18:17 +03:00
}
}
/* and move it onto our toplevel hierarchy. */
( void ) talloc_move ( mem_ctx , & intermediate_ptr ) ;
/* Tell the sub-threads we're ready for another. */
pthread_cond_broadcast ( & condvar ) ;
2016-10-12 13:27:56 +03:00
ret = pthread_mutex_unlock ( & mtx ) ;
assert ( ret = = 0 ) ;
2015-03-16 22:18:17 +03:00
}
CHECK_SIZE ( " pthread_talloc_passing " , mem_ctx , NUM_THREADS * 100 ) ;
# if 1
/* Dump the hierarchy. */
talloc_report ( mem_ctx , stdout ) ;
# endif
talloc_free ( mem_ctx ) ;
printf ( " success: pthread_talloc_passing \n " ) ;
return true ;
}
# endif
2015-09-02 04:30:31 +03:00
static void test_magic_protection_abort ( const char * reason )
{
/* exit with errcode 42 to communicate successful test to the parent process */
if ( strcmp ( reason , " Bad talloc magic value - unknown value " ) = = 0 ) {
_exit ( 42 ) ;
} else {
printf ( " talloc aborted for an unexpected reason \n " ) ;
}
}
2016-06-30 02:51:26 +03:00
static int test_magic_protection_destructor ( int * ptr )
{
_exit ( 404 ) ; /* Not 42 */
}
2015-09-02 04:30:31 +03:00
static bool test_magic_protection ( void )
{
void * pool = talloc_pool ( NULL , 1024 ) ;
int * p1 , * p2 ;
pid_t pid ;
int exit_status ;
printf ( " test: magic_protection \n " ) ;
p1 = talloc ( pool , int ) ;
p2 = talloc ( pool , int ) ;
/* To avoid complaints from the compiler assign values to the p1 & p2. */
* p1 = 6 ;
* p2 = 9 ;
pid = fork ( ) ;
if ( pid = = 0 ) {
talloc_set_abort_fn ( test_magic_protection_abort ) ;
2016-06-30 02:51:26 +03:00
talloc_set_destructor ( p2 , test_magic_protection_destructor ) ;
2015-09-02 04:30:31 +03:00
/*
* Simulate a security attack
* by triggering a buffer overflow in memset to overwrite the
* constructor in the next pool chunk .
*
* Real attacks would attempt to set a real destructor .
*/
memset ( p1 , ' \0 ' , 32 ) ;
/* Then the attack takes effect when the memory's freed. */
talloc_free ( pool ) ;
2015-10-12 13:06:50 +03:00
/* Never reached. Make compilers happy */
return true ;
2015-09-02 04:30:31 +03:00
}
2015-10-12 13:06:50 +03:00
while ( wait ( & exit_status ) ! = pid ) ;
2019-08-15 15:43:22 +03:00
talloc_free ( pool ) ; /* make ASAN happy */
2015-09-02 04:30:31 +03:00
if ( ! WIFEXITED ( exit_status ) ) {
printf ( " Child exited through unexpected abnormal means \n " ) ;
return false ;
}
if ( WEXITSTATUS ( exit_status ) ! = 42 ) {
printf ( " Child exited with wrong exit status \n " ) ;
return false ;
}
if ( WIFSIGNALED ( exit_status ) ) {
2019-08-29 23:02:13 +03:00
printf ( " Child received unexpected signal \n " ) ;
2015-09-02 04:30:31 +03:00
return false ;
}
printf ( " success: magic_protection \n " ) ;
return true ;
}
2018-01-12 01:17:09 +03:00
static void test_magic_free_protection_abort ( const char * reason )
{
/* exit with errcode 42 to communicate successful test to the parent process */
if ( strcmp ( reason , " Bad talloc magic value - access after free " ) = = 0 ) {
_exit ( 42 ) ;
}
/* not 42 */
_exit ( 404 ) ;
}
static bool test_magic_free_protection ( void )
{
void * pool = talloc_pool ( NULL , 1024 ) ;
int * p1 , * p2 , * p3 ;
pid_t pid ;
int exit_status ;
printf ( " test: magic_free_protection \n " ) ;
p1 = talloc ( pool , int ) ;
p2 = talloc ( pool , int ) ;
/* To avoid complaints from the compiler assign values to the p1 & p2. */
* p1 = 6 ;
* p2 = 9 ;
p3 = talloc_realloc ( pool , p2 , int , 2048 ) ;
torture_assert ( " pool realloc 2048 " ,
p3 ! = p2 ,
" failed: pointer not changed " ) ;
/*
* Now access the memory in the pool after the realloc ( ) . It
* should be marked as free , so use of the old pointer should
* trigger the abort function
*/
pid = fork ( ) ;
if ( pid = = 0 ) {
talloc_set_abort_fn ( test_magic_free_protection_abort ) ;
talloc_get_name ( p2 ) ;
/* Never reached. Make compilers happy */
return true ;
}
while ( wait ( & exit_status ) ! = pid ) ;
if ( ! WIFEXITED ( exit_status ) ) {
printf ( " Child exited through unexpected abnormal means \n " ) ;
return false ;
}
if ( WEXITSTATUS ( exit_status ) ! = 42 ) {
printf ( " Child exited with wrong exit status \n " ) ;
return false ;
}
if ( WIFSIGNALED ( exit_status ) ) {
2019-08-29 23:02:13 +03:00
printf ( " Child received unexpected signal \n " ) ;
2018-01-12 01:17:09 +03:00
return false ;
}
talloc_free ( pool ) ;
printf ( " success: magic_free_protection \n " ) ;
return true ;
}
2009-07-13 20:52:44 +04:00
static void test_reset ( void )
{
2009-07-30 00:00:05 +04:00
talloc_set_log_fn ( test_log_stdout ) ;
2009-07-14 13:58:16 +04:00
test_abort_stop ( ) ;
2009-07-13 20:52:44 +04:00
talloc_disable_null_tracking ( ) ;
2009-09-21 00:14:40 +04:00
talloc_enable_null_tracking_no_autofree ( ) ;
2009-07-13 20:52:44 +04:00
}
2007-04-19 13:08:53 +04:00
bool torture_local_talloc ( struct torture_context * tctx )
2005-05-03 11:33:49 +04:00
{
2006-09-22 08:16:58 +04:00
bool ret = true ;
2005-05-03 11:33:49 +04:00
2007-04-19 13:08:53 +04:00
setlinebuf ( stdout ) ;
2013-09-07 02:30:38 +04:00
test_reset ( ) ;
ret & = test_pooled_object ( ) ;
2013-09-07 01:52:28 +04:00
test_reset ( ) ;
ret & = test_pool_nest ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_ref1 ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_ref2 ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_ref3 ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_ref4 ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_unlink1 ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_misc ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_realloc ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_realloc_child ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_steal ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_move ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_unref_reparent ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_realloc_fn ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_type ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_lifeless ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_loop ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_free_parent_deny_child ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2016-11-24 03:57:54 +03:00
ret & = test_realloc_on_destructor_parent ( ) ;
test_reset ( ) ;
2015-03-04 04:12:32 +03:00
ret & = test_free_parent_reparent_child ( ) ;
test_reset ( ) ;
ret & = test_free_parent_reparent_child_in_pool ( ) ;
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_talloc_ptrtype ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2007-05-08 15:12:11 +04:00
ret & = test_talloc_free_in_destructor ( ) ;
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2008-01-05 20:26:54 +03:00
ret & = test_pool ( ) ;
2010-04-20 09:30:57 +04:00
test_reset ( ) ;
2011-05-16 21:25:47 +04:00
ret & = test_pool_steal ( ) ;
test_reset ( ) ;
2010-04-20 09:30:57 +04:00
ret & = test_free_ref_null_context ( ) ;
2010-12-22 07:29:37 +03:00
test_reset ( ) ;
ret & = test_rusty ( ) ;
2011-07-29 05:57:07 +04:00
test_reset ( ) ;
ret & = test_free_children ( ) ;
2012-09-23 00:35:21 +04:00
test_reset ( ) ;
ret & = test_memlimit ( ) ;
2015-03-16 22:18:17 +03:00
# ifdef HAVE_PTHREAD
test_reset ( ) ;
ret & = test_pthread_talloc_passing ( ) ;
# endif
2012-09-23 00:35:21 +04:00
2006-10-21 04:23:27 +04:00
2005-05-03 11:33:49 +04:00
if ( ret ) {
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_speed ( ) ;
2005-05-03 11:33:49 +04:00
}
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2006-10-21 04:23:27 +04:00
ret & = test_autofree ( ) ;
2015-09-02 04:30:31 +03:00
test_reset ( ) ;
ret & = test_magic_protection ( ) ;
2018-01-12 01:17:09 +03:00
test_reset ( ) ;
ret & = test_magic_free_protection ( ) ;
2005-05-03 11:33:49 +04:00
2009-07-13 20:52:44 +04:00
test_reset ( ) ;
2011-04-04 17:53:46 +04:00
talloc_disable_null_tracking ( ) ;
2007-04-19 13:08:53 +04:00
return ret ;
}