Return-Path: Delivered-To: apmail-incubator-stdcxx-dev-archive@www.apache.org Received: (qmail 56934 invoked from network); 23 Jan 2006 21:02:17 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 23 Jan 2006 21:02:17 -0000 Received: (qmail 48746 invoked by uid 500); 23 Jan 2006 21:02:17 -0000 Delivered-To: apmail-incubator-stdcxx-dev-archive@incubator.apache.org Received: (qmail 48733 invoked by uid 500); 23 Jan 2006 21:02:17 -0000 Mailing-List: contact stdcxx-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-dev@incubator.apache.org Received: (qmail 48722 invoked by uid 99); 23 Jan 2006 21:02:16 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Jan 2006 13:02:16 -0800 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests= X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: local policy) Received: from [12.17.213.84] (HELO bco-exchange.bco.roguewave.com) (12.17.213.84) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Jan 2006 13:02:15 -0800 Received: from [10.70.2.6] (skynet.bco.roguewave.com [10.70.2.6]) by bco-exchange.bco.roguewave.com with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2657.72) id ZGW28H8G; Mon, 23 Jan 2006 13:54:54 -0700 Message-ID: <43D544C9.7070502@roguewave.com> Date: Mon, 23 Jan 2006 14:04:09 -0700 From: Liviu Nicoara User-Agent: Mozilla Thunderbird 1.0.7 (X11/20050923) X-Accept-Language: en-us, en MIME-Version: 1.0 To: stdcxx-dev@incubator.apache.org Subject: 0.new.cpp References: <43CE6FAC.3000507@moscow.vdiweb.com> <43CFE7F6.4060208@roguewave.com> <43D01A83.4020206@roguewave.com> <43D5298C.2060009@roguewave.com> <43D542BD.7040305@roguewave.com> In-Reply-To: <43D542BD.7040305@roguewave.com> Content-Type: multipart/mixed; boundary="------------070602080404020607050205" X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N --------------070602080404020607050205 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit I have attached my attempt at converting new.cpp "self" test to the new driver. Liviu --------------070602080404020607050205 Content-Type: text/x-c++src; name="0.new.cpp" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="0.new.cpp" /*************************************************************************** * * 0.new.cpp - test exercising replacement operator new and delete * * $Id$ * *************************************************************************** * * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave * Software division. Licensed 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 #include #include #include #include #include #include int exit_status /* = 0 */; extern "C" { int line; int fail; jmp_buf env; void handle_ABRT (int) { fail = 0; longjmp (env, 1); } } #define FAIL(code) \ fail = line = __LINE__; \ signal (SIGABRT, handle_ABRT); \ if (0 == setjmp (env)) { \ code; \ exit_status = 1; \ rw_assert (false, __FILE__, line, "expected assertion"); \ } \ else \ (void)0 #define PASS(code) \ fail = -1; line = __LINE__; \ signal (SIGABRT, handle_ABRT); \ if (0 == setjmp (env)) \ code; \ else if (fail != line) { \ exit_status = 1; \ rw_assert (false, __FILE__, line, "unexpected assertion"); \ } (void)0 /**************************************************************************/ void test_new_delete () { rw_info (0, __FILE__, __LINE__, "exercising successful allocation and deallocation"); { void *p = 0; PASS (p = operator new (0)); rw_assert (p != 0, __FILE__, __LINE__, "operator new(0) != 0"); operator delete (p); } { void *p = 0; PASS (p = operator new (1)); rw_assert (p != 0, __FILE__, __LINE__, "operator new(1) != 0"); operator delete (p); } { void *p = 0; PASS (p = operator new (2)); rw_assert (p != 0, __FILE__, __LINE__, "operator new(2) != 0"); operator delete (p); } { void *p = 0; PASS (p = operator new (1024)); rw_assert (p != 0, __FILE__, __LINE__, "operator new(1024) != 0"); operator delete (p); } } /**************************************************************************/ #define CATCH(code) \ try { code; fail = 1; } \ catch (_RWSTD_BAD_ALLOC) { fail = 0; } \ catch (...) { fail = 2; } \ rw_assert (!fail, __FILE__, __LINE__, \ "%s", 1 == fail ? "failed to throw" : \ "threw an unknown exception") #define NOTHROW(code) \ try { fail = 0; code; } \ catch (...) { fail = 1; } \ rw_assert (!fail, __FILE__, __LINE__, "unexpected exception") void test_bad_alloc () { rw_info (0, __FILE__, __LINE__, "exercising the ability of ordinary " "operator new to throw std::bad_alloc"); rwt_free_store* const pst = rwt_get_free_store (0); *pst->throw_at_blocks_ [0] = pst->blocks_ [0]; CATCH (operator new (0)); CATCH (operator new (1)); CATCH (operator new (2)); CATCH (operator new (1024)); { void *p = 0; NOTHROW (p = operator new[](0)); operator delete[](p); } { void *p = 0; NOTHROW (p = operator new[](1)); operator delete[](p); } { void *p = 0; NOTHROW (p = operator new[](2)); operator delete[](p); } { void *p = 0; NOTHROW (p = operator new[](1024)); operator delete[](p); } rw_info (0, __FILE__, __LINE__, "exercising the ability of the array form " "of operator new to throw std::bad_alloc"); *pst->throw_at_blocks_ [0] = std::size_t (-1); *pst->throw_at_blocks_ [1] = pst->blocks_ [1]; CATCH (operator new[](0)); CATCH (operator new[](1)); CATCH (operator new[](2)); CATCH (operator new[](1024)); { void *p = 0; NOTHROW (p = operator new (0)); rw_assert (p != 0, __FILE__, __LINE__, "operator new[](0) != 0"); operator delete (p); } { void *p = 0; NOTHROW (p = operator new (1)); rw_assert (p != 0, __FILE__, __LINE__, "operator new[](1) != 0"); operator delete (p); } { void *p = 0; NOTHROW (p = operator new (32)); rw_assert (p != 0, __FILE__, __LINE__, "operator new[](32) != 0"); operator delete (p); } { void *p = 0; NOTHROW (p = operator new (4096)); rw_assert (p != 0, __FILE__, __LINE__, "operator new[](4096) != 0"); operator delete (p); } *pst->throw_at_blocks_ [1] = std::size_t (-1); } /**************************************************************************/ void test_new_delete_mismatch () { rw_info (0, __FILE__, __LINE__, "exercising the ability to detect " "allocation/deallocation mismatches"); { // detect allocations by operator new() deallocated // using (the array form of) operator delete[] void *p = 0; PASS (p = operator new (0)); FAIL (operator delete[](p)); PASS (operator delete (p)); } { void *p = 0; PASS (p = operator new (1)); FAIL (operator delete[](p)); PASS (operator delete (p)); } { void *p = 0; PASS (p = operator new[](33)); FAIL (operator delete (p)); PASS (operator delete[] (p)); } } /**************************************************************************/ void test_bad_delete () { rw_info (0, __FILE__, __LINE__, "exercising the ability to detect " "deletion of unallocated storage"); { char *p = 0; PASS (p = new char); FAIL (delete (p - 1)); FAIL (delete (p + 1)); PASS (delete (p)); } { char *p = 0; PASS (p = new char [4]); FAIL (delete (p - 1)); FAIL (delete (p + 1)); FAIL (delete (p + 2)); FAIL (delete (p + 3)); FAIL (delete (p + 4)); FAIL (delete[] (p - 1)); FAIL (delete[] (p + 1)); FAIL (delete[] (p + 2)); FAIL (delete[] (p + 3)); FAIL (delete[] (p + 4)); PASS (delete[] p); } } /**************************************************************************/ void test_double_delete () { rw_info (0, __FILE__, __LINE__, "exercising the ability to detect double deletion"); { char *p = 0; PASS (p = new char); PASS (delete (p)); FAIL (delete (p)); } { char *p = 0; PASS (p = new char [32]); PASS (delete[] p); FAIL (delete[] p); FAIL (delete p); } } /**************************************************************************/ void test_corruption () { rw_info (0, __FILE__, __LINE__, "exercising the ability to detect memory corruption"); // corrupt (and restore) memory past the end of the allocated block for (std::size_t i = 1; i != 8; ++i) { char *p = 0; PASS (p = new char); // save the value of the byte past the end of the block // and temporarily overwrite it with another value const char save = p [i]; p [i] = ~p [i]; // expect operator delete to diagnose the corruption // and call abort() without actually freeing the block FAIL (delete p); // restore the corrupted byte to its original value p [i] = save; // expect operator delete not to complain PASS (delete p); } } /**************************************************************************/ #define LEAK(code, bytes, blks) \ do { \ /* establish a checkpoint for memory leaks */ \ rwt_check_leaks (0, 0); \ \ code; \ \ /* find memory leaks since the last checkpoint */ \ std::size_t nbytes; \ const std::size_t nblocks = rwt_check_leaks (&nbytes, 0); \ \ rw_assert (blks == nblocks && bytes == nbytes, \ __FILE__, __LINE__, \ "failed to detect a leak of %d bytes in " \ "%d blocks: got %zu bytes in %zu blocks", \ bytes, blks, nbytes, nblocks); \ } while (0) void test_leaks () { rw_info (0, __FILE__, __LINE__, "exercising the ability to detect memory leaks"); { void *p = 0; LEAK (p = operator new (0), 0, 1); PASS (operator delete (p)); } { void *p = 0; LEAK (p = operator new (1), 1, 1); PASS (operator delete (p)); } { void *p = 0; LEAK (p = operator new (1234), 1234, 1); PASS (operator delete (p)); } { void *p0 = 0; void *p1 = 0; LEAK (p0 = operator new (32); p1 = operator new (64), 96, 2); PASS (operator delete (p0)); PASS (operator delete (p1)); } { void *p = 0; LEAK (p = operator new[] (12345), 12345, 1); PASS (operator delete[] (p)); } } /**************************************************************************/ void stress_test () { rw_info (0, __FILE__, __LINE__, "stress-testing replacement operators new and delete"); rwt_free_store* const pst = rwt_get_free_store (0); std::size_t nblocks = pst->blocks_ [0] + pst->blocks_ [1]; std::size_t nbytes = pst->bytes_ [0] + pst->bytes_ [1]; void* ptrs [1000]; const std::size_t N = sizeof ptrs / sizeof *ptrs; for (std::size_t i = 0; i != N; ++i) { if (i % 2) { PASS (ptrs [i] = operator new[](i)); } else { PASS (ptrs [i] = operator new (i)); } } for (std::size_t i = 0; i < N; ++i) { const std::size_t j = (i * (i + 17)) % N; if (j % 2) { PASS (operator delete[](ptrs [j])); } else { PASS (operator delete (ptrs [j])); } ptrs [j] = 0; } for (std::size_t i = 0; i < N; ++i) { if (i % 2) { PASS (operator delete[](ptrs [i])); } else { PASS (operator delete (ptrs [i])); } } nblocks = pst->blocks_ [0] + pst->blocks_ [1] - nblocks; nbytes = pst->bytes_ [0] + pst->bytes_ [1] - nbytes; rw_assert (0 == nblocks && 0 == nbytes, __FILE__, __LINE__, "false leaks detected: %zu bytes in %zu blocks", nbytes, nblocks); } /**************************************************************************/ int run_test (int, char**) { test_new_delete (); test_bad_alloc (); test_new_delete_mismatch (); test_double_delete (); test_bad_delete (); test_corruption (); test_leaks (); stress_test (); return 0; } /**************************************************************************/ int main (int argc, char** argv) { return rw_test (argc, argv, __FILE__, 0 /* no clause */, 0 /* no comment */, run_test, 0); } --------------070602080404020607050205--