2009-09-22 Ramon Novoa <rnovoa@artica.es>
* debug_new.h, fast_mutex.h, debug_new.cpp, static_assert.h: Added to repository. Wu Yongwei's memory leak detection tool (part of Nvwa). Only compiled when debugging is enabled. * bin/util/tentacle_client.exe: Added to repository. Tentacle client needed to build the installer. * installer/pandora_2.0.mpi: moved to installer/pandora.mpi. Updated. The installer can now be built directly from the installer subdirectory. * configure.in, Makefile.am, autogen.sh: Created a proper configure.in and Makefile.am. The agent can now be cross-compiled from Linux :-D * bin/pandora_agent.conf: Fixed. A local configuration had been uploaded. * pandora_windows_service.h,pandora_windows_service.cc, udp_server/udp_server.cc, udp_server/udp_server.h: Properly shutdown the UDP server. * modules/pandora_module_regexp.cc, modules/pandora_module_inventory.cc, modules/pandora_module_factory.cc, modules/pandora_module.cc, pandora_strutils.cc, pandora.h, pandora.cc: Fixed a couple of memory leaks. Small changes to avoid compile warnings when cross-compiling from Linux. * windows_service.cc: Removed the interactive service flag to avoid 'black windows'. * main.cc: Include the memory leak detection tool if debugging is enabled. git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@1966 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
parent
d9dfbd1a29
commit
f8e8bffe90
|
@ -1,3 +1,41 @@
|
|||
2009-09-22 Ramon Novoa <rnovoa@artica.es>
|
||||
|
||||
* debug_new.h, fast_mutex.h,
|
||||
debug_new.cpp, static_assert.h: Added to repository. Wu Yongwei's
|
||||
memory leak detection tool (part of Nvwa). Only compiled when
|
||||
debugging is enabled.
|
||||
|
||||
* bin/util/tentacle_client.exe: Added to repository. Tentacle client
|
||||
needed to build the installer.
|
||||
|
||||
* installer/pandora_2.0.mpi: moved to installer/pandora.mpi. Updated.
|
||||
The installer can now be built directly from the installer
|
||||
subdirectory.
|
||||
|
||||
* configure.in, Makefile.am, autogen.sh: Created a proper
|
||||
configure.in and Makefile.am. The agent can now be cross-compiled
|
||||
from Linux :-D
|
||||
|
||||
* bin/pandora_agent.conf: Fixed. A local configuration had been
|
||||
uploaded.
|
||||
|
||||
* pandora_windows_service.h,pandora_windows_service.cc,
|
||||
udp_server/udp_server.cc, udp_server/udp_server.h: Properly shutdown
|
||||
the UDP server.
|
||||
|
||||
* modules/pandora_module_regexp.cc,
|
||||
modules/pandora_module_inventory.cc,
|
||||
modules/pandora_module_factory.cc,
|
||||
modules/pandora_module.cc, pandora_strutils.cc,
|
||||
pandora.h, pandora.cc: Fixed a couple of memory leaks. Small changes
|
||||
to avoid compile warnings when cross-compiling from Linux.
|
||||
|
||||
* windows_service.cc: Removed the interactive service flag to avoid
|
||||
'black windows'.
|
||||
|
||||
* main.cc: Include the memory leak detection tool if debugging is
|
||||
enabled.
|
||||
|
||||
2009-09-16 Ramon Novoa <rnovoa@artica.es>
|
||||
|
||||
* pandora_windows_service.cc: Fixed a memory leak.
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
bin_PROGRAMS = PandoraAgent
|
||||
if DEBUG
|
||||
PandoraAgent_SOURCES = misc/pandora_file.cc modules/pandora_data.cc modules/pandora_module_factory.cc modules/pandora_module.cc modules/pandora_module_list.cc modules/pandora_module_inventory.cc modules/pandora_module_freememory.cc modules/pandora_module_exec.cc modules/pandora_module_odbc.cc modules/pandora_module_perfcounter.cc modules/pandora_module_proc.cc modules/pandora_module_tcpcheck.cc modules/pandora_module_freememory_percent.cc modules/pandora_module_freedisk.cc modules/pandora_module_freedisk_percent.cc modules/pandora_module_logevent.cc modules/pandora_module_service.cc modules/pandora_module_cpuusage.cc modules/pandora_module_wmiquery.cc modules/pandora_module_regexp.cc udp_server/udp_server.cc main.cc pandora_strutils.cc pandora.cc windows_service.cc pandora_agent_conf.cc windows/pandora_windows_info.cc windows/pandora_wmi.cc pandora_windows_service.cc tinyxml/tinyxmlerror.cpp tinyxml/tinyxml.cpp tinyxml/tinyxmlparser.cpp tinyxml/tinystr.cpp misc/md5.c windows/wmi/disphelper.c ssh/libssh2/channel.c ssh/libssh2/mac.c ssh/libssh2/session.c ssh/libssh2/comp.c ssh/libssh2/misc.c ssh/libssh2/sftp.c ssh/libssh2/crypt.c ssh/libssh2/packet.c ssh/libssh2/userauth.c ssh/libssh2/hostkey.c ssh/libssh2/publickey.c ssh/libssh2/kex.c ssh/libssh2/scp.c ssh/pandora_ssh_client.cc ssh/pandora_ssh_test.cc ftp/pandora_ftp_client.cc ftp/pandora_ftp_test.cc debug_new.cpp
|
||||
PandoraAgent_CXXFLAGS=-g -O0 -DCURL_STATICLIB -D__DEBUG__
|
||||
else
|
||||
PandoraAgent_SOURCES = misc/pandora_file.cc modules/pandora_data.cc modules/pandora_module_factory.cc modules/pandora_module.cc modules/pandora_module_list.cc modules/pandora_module_inventory.cc modules/pandora_module_freememory.cc modules/pandora_module_exec.cc modules/pandora_module_odbc.cc modules/pandora_module_perfcounter.cc modules/pandora_module_proc.cc modules/pandora_module_tcpcheck.cc modules/pandora_module_freememory_percent.cc modules/pandora_module_freedisk.cc modules/pandora_module_freedisk_percent.cc modules/pandora_module_logevent.cc modules/pandora_module_service.cc modules/pandora_module_cpuusage.cc modules/pandora_module_wmiquery.cc modules/pandora_module_regexp.cc udp_server/udp_server.cc main.cc pandora_strutils.cc pandora.cc windows_service.cc pandora_agent_conf.cc windows/pandora_windows_info.cc windows/pandora_wmi.cc pandora_windows_service.cc tinyxml/tinyxmlerror.cpp tinyxml/tinyxml.cpp tinyxml/tinyxmlparser.cpp tinyxml/tinystr.cpp misc/md5.c windows/wmi/disphelper.c ssh/libssh2/channel.c ssh/libssh2/mac.c ssh/libssh2/session.c ssh/libssh2/comp.c ssh/libssh2/misc.c ssh/libssh2/sftp.c ssh/libssh2/crypt.c ssh/libssh2/packet.c ssh/libssh2/userauth.c ssh/libssh2/hostkey.c ssh/libssh2/publickey.c ssh/libssh2/kex.c ssh/libssh2/scp.c ssh/pandora_ssh_client.cc ssh/pandora_ssh_test.cc ftp/pandora_ftp_client.cc ftp/pandora_ftp_test.cc
|
||||
PandoraAgent_CXXFLAGS=-O2 -DCURL_STATICLIB
|
||||
endif
|
|
@ -1,43 +1,6 @@
|
|||
#! /bin/sh
|
||||
|
||||
# $Id: autogen.sh,v 1.4 2002/12/02 01:39:49 murrayc Exp $
|
||||
#
|
||||
# Copyright (c) 2002 Daniel Elstner <daniel.elstner@gmx.net>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License VERSION 2 as
|
||||
# published by the Free Software Foundation. You are not allowed to
|
||||
# use any other version of the license; unless you got the explicit
|
||||
# permission from the author to do so.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
dir=`echo "$0" | sed 's,[^/]*$,,'`
|
||||
test "x${dir}" = "x" && dir='.'
|
||||
|
||||
if test "x`cd "${dir}" 2>/dev/null && pwd`" != "x`pwd`"
|
||||
then
|
||||
echo "This script must be executed directly from the source directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -f config.cache acconfig.h
|
||||
|
||||
echo "- Running aclocal." && \
|
||||
aclocal && \
|
||||
echo "- Running autoconf." && \
|
||||
autoconf && \
|
||||
echo "- Running automake." && \
|
||||
automake --add-missing --gnu && \
|
||||
echo && \
|
||||
./configure "$@" && exit 0
|
||||
|
||||
exit 1
|
||||
|
||||
#!/bin/sh
|
||||
touch NEWS
|
||||
aclocal \
|
||||
&& autoconf \
|
||||
&& autoheader \
|
||||
&& automake --add-missing
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Base config file for Pandora FMS Windows Agent
|
||||
# (c) 2006-2008 Artica Soluciones Tecnologicas
|
||||
# (c) 2006-2009 Artica Soluciones Tecnologicas
|
||||
# Version 3.0
|
||||
|
||||
# This program is Free Software, you can redistribute it and/or modify it
|
||||
|
@ -16,19 +16,19 @@
|
|||
|
||||
# The variables $*$ will be substituted in the installation
|
||||
|
||||
server_ip 192.168.50.72
|
||||
server_path /var/spool/pandora/data_in
|
||||
temporal "c:\tmp\"
|
||||
server_ip $ServerIP$
|
||||
server_path $ServerPath$
|
||||
temporal "$AgentTemp$"
|
||||
#temporal_min_size 1024
|
||||
#startup_delay 5
|
||||
|
||||
# Agent uses your hostname automatically, if you need to change agent name
|
||||
# use directive agent_name
|
||||
agent_name test_guindous
|
||||
# agent_name $AgentName$
|
||||
|
||||
# Interval is defined in seconds
|
||||
|
||||
interval 5
|
||||
interval 300
|
||||
|
||||
# tranfer_modes: Possible values are local, tentacle (default), ftp and ssh.
|
||||
transfer_mode tentacle
|
||||
|
@ -38,7 +38,7 @@ server_port 41121
|
|||
# server_pwd pandora
|
||||
|
||||
# Debug mode do not copy XML data files to server and stop executing after first one
|
||||
#debug 1
|
||||
# debug 1
|
||||
|
||||
# ODBC connections
|
||||
# Configuring "ExampleDSN" DSN. Notice that this DSN connection must be configured
|
||||
|
@ -98,39 +98,20 @@ server_port 41121
|
|||
#module_end
|
||||
|
||||
# CPU usage percentage
|
||||
#module_begin
|
||||
#module_name CPUUse0
|
||||
#module_type generic_data
|
||||
#module_cpuusage 0
|
||||
#module_description CPU#0 usage
|
||||
#module_end
|
||||
|
||||
# Inventory
|
||||
#module_begin
|
||||
#module_name Inventory
|
||||
# Establish the module interval to run every 3 days (8640 times interval (30 seconds in this case) = 3 days)
|
||||
#module_interval 8640
|
||||
#module_type generic_data_string
|
||||
#Parameters available:
|
||||
# * CPU -> Gets information about the CPUs
|
||||
# * CDROM -> Gets information about the CDROMs
|
||||
# * Video -> Gets information about the video cards
|
||||
# * HD -> Gets information about the Hard Drives
|
||||
# * NIC -> Gets information about the Network Interface Controlers
|
||||
# * Patches -> Gets informaton about the patches installed
|
||||
# * Software -> Gets information about the MSI packages installed
|
||||
# * RAM -> Get information about the RAM modules
|
||||
#module_inventory CPU Video HDs NICs CDROM Patches Software RAM
|
||||
#module_description Inventory
|
||||
#module_end
|
||||
module_begin
|
||||
module_name CPUUse0
|
||||
module_type generic_data
|
||||
module_cpuusage 0
|
||||
module_description CPU#0 usage
|
||||
module_end
|
||||
|
||||
# Free Memory
|
||||
#module_begin
|
||||
#module_name FreeMemory
|
||||
#module_type generic_data_string
|
||||
#module_freememory
|
||||
#module_description Amount of free memory.
|
||||
#module_end
|
||||
module_begin
|
||||
module_name FreeMemory
|
||||
module_type generic_data
|
||||
module_freememory
|
||||
module_description Amount of free memory.
|
||||
module_end
|
||||
|
||||
# Log events
|
||||
#module_begin
|
||||
|
@ -272,14 +253,14 @@ server_port 41121
|
|||
# module_end
|
||||
|
||||
# Example of watchdog service opening it if it gets closed
|
||||
module_begin
|
||||
module_name ServiceSched
|
||||
module_type generic_proc
|
||||
module_service Schedule
|
||||
module_description Service Task scheduler
|
||||
module_async yes
|
||||
module_watchdog yes
|
||||
module_end
|
||||
# module_begin
|
||||
# module_name ServiceSched
|
||||
# module_type generic_proc
|
||||
# module_service Schedule
|
||||
# module_description Service Task scheduler
|
||||
# module_async yes
|
||||
# module_watchdog yes
|
||||
# module_end
|
||||
|
||||
# Example UDP server to be able to execute remote actions such
|
||||
# as starting or stopping process.
|
||||
|
|
Binary file not shown.
|
@ -1,10 +1,54 @@
|
|||
AC_PREREQ(2.59)
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([pandora-agent-win32], [1.0.0])
|
||||
AC_PREREQ([2.63])
|
||||
AC_INIT([Pandora Agent], [3.0], [rnovoa@artica.es])
|
||||
AC_CONFIG_SRCDIR([pandora_strutils.h])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
|
||||
AC_CANONICAL_SYSTEM
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
AC_OUTPUT([
|
||||
Doxyfile
|
||||
Makefile
|
||||
])
|
||||
# Checks for programs.
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CC
|
||||
|
||||
# Get rid of the -g flag
|
||||
CXXFLAGS=
|
||||
|
||||
# Debugging
|
||||
AC_ARG_ENABLE([debug], [ --enable-debug produce debugging information (disabled by default)], debug="yes", debug="no")
|
||||
AM_CONDITIONAL(DEBUG, test "$debug" = "yes")
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([ws2_32], [main], , AC_MSG_ERROR([MingGW not found. You can get it from http://www.mingw.org/]))
|
||||
AC_CHECK_LIB([psapi], [main], , )
|
||||
AC_CHECK_LIB([ole32], [main], , )
|
||||
AC_CHECK_LIB([oleaut32], [main], , )
|
||||
AC_CHECK_LIB([uuid], [main], , )
|
||||
AC_CHECK_LIB([regex], [main], , AC_MSG_ERROR([Boost.Regex not not found. Get it from http://www.boost.org/ and rename it to libregex.a]))
|
||||
AC_CHECK_LIB([z], [main], , )
|
||||
AC_CHECK_LIB([gdi32], [main], , )
|
||||
AC_CHECK_LIB([crypto], [main], , )
|
||||
AC_CHECK_LIB([ssl], [main], , )
|
||||
AC_CHECK_LIB([curl], [main], , )
|
||||
AC_CHECK_LIB([odbc++], [main], , )
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([fcntl.h stddef.h stdlib.h string.h sys/socket.h sys/time.h unistd.h wchar.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_HEADER_STDBOOL
|
||||
AC_C_INLINE
|
||||
AC_TYPE_SIZE_T
|
||||
AC_CHECK_TYPES([ptrdiff_t])
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_ERROR_AT_LINE
|
||||
AC_FUNC_MALLOC
|
||||
AC_FUNC_MKTIME
|
||||
AC_FUNC_REALLOC
|
||||
AC_CHECK_FUNCS([floor gethostbyname gettimeofday inet_ntoa memchr memmove memset regcomp select socket strchr strdup strrchr strtol])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
|
|
@ -0,0 +1,839 @@
|
|||
// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||
// vim:tabstop=4:shiftwidth=4:expandtab:
|
||||
|
||||
/*
|
||||
* Copyright (C) 2004-2007 Wu Yongwei <adah at users dot sourceforge dot net>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute
|
||||
* it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must
|
||||
* not claim that you wrote the original software. If you use this
|
||||
* software in a product, an acknowledgement in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must
|
||||
* not be misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* This file is part of Stones of Nvwa:
|
||||
* http://sourceforge.net/projects/nvwa
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file debug_new.cpp
|
||||
*
|
||||
* Implementation of debug versions of new and delete to check leakage.
|
||||
*
|
||||
* @version 4.12, 2007/12/31
|
||||
* @author Wu Yongwei
|
||||
*
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef __unix__
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include "fast_mutex.h"
|
||||
#include "static_assert.h"
|
||||
|
||||
#if !_FAST_MUTEX_CHECK_INITIALIZATION && !defined(_NOTHREADS)
|
||||
#error "_FAST_MUTEX_CHECK_INITIALIZATION not set: check_leaks may not work"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def _DEBUG_NEW_ALIGNMENT
|
||||
*
|
||||
* The alignment requirement of allocated memory blocks. It must be a
|
||||
* power of two.
|
||||
*/
|
||||
#ifndef _DEBUG_NEW_ALIGNMENT
|
||||
#define _DEBUG_NEW_ALIGNMENT 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def _DEBUG_NEW_CALLER_ADDRESS
|
||||
*
|
||||
* The expression to return the caller address. #print_position will
|
||||
* later on use this address to print the position information of memory
|
||||
* operation points.
|
||||
*/
|
||||
#ifndef _DEBUG_NEW_CALLER_ADDRESS
|
||||
#ifdef __GNUC__
|
||||
#define _DEBUG_NEW_CALLER_ADDRESS __builtin_return_address(0)
|
||||
#else
|
||||
#define _DEBUG_NEW_CALLER_ADDRESS NULL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def _DEBUG_NEW_ERROR_ACTION
|
||||
*
|
||||
* The action to take when an error occurs. The default behaviour is to
|
||||
* call \e abort, unless \c _DEBUG_NEW_ERROR_CRASH is defined, in which
|
||||
* case a segmentation fault will be triggered instead (which can be
|
||||
* useful on platforms like Windows that do not generate a core dump
|
||||
* when \e abort is called).
|
||||
*/
|
||||
#ifndef _DEBUG_NEW_ERROR_ACTION
|
||||
#ifndef _DEBUG_NEW_ERROR_CRASH
|
||||
#define _DEBUG_NEW_ERROR_ACTION abort()
|
||||
#else
|
||||
#define _DEBUG_NEW_ERROR_ACTION do { *((char*)0) = 0; abort(); } while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def _DEBUG_NEW_FILENAME_LEN
|
||||
*
|
||||
* The length of file name stored if greater than zero. If it is zero,
|
||||
* only a const char pointer will be stored. Currently the default
|
||||
* behaviour is to copy the file name, because I found that the exit
|
||||
* leakage check cannot access the address of the file name sometimes
|
||||
* (in my case, a core dump will occur when trying to access the file
|
||||
* name in a shared library after a \c SIGINT). The current default
|
||||
* value makes the size of new_ptr_list_t 64 on 32-bit platforms.
|
||||
*/
|
||||
#ifndef _DEBUG_NEW_FILENAME_LEN
|
||||
#define _DEBUG_NEW_FILENAME_LEN 44
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def _DEBUG_NEW_PROGNAME
|
||||
*
|
||||
* The program (executable) name to be set at compile time. It is
|
||||
* better to assign the full program path to #new_progname in \e main
|
||||
* (at run time) than to use this (compile-time) macro, but this macro
|
||||
* serves well as a quick hack. Note also that double quotation marks
|
||||
* need to be used around the program name, i.e., one should specify a
|
||||
* command-line option like <code>-D_DEBUG_NEW_PROGNAME=\"a.out\"</code>
|
||||
* in \e bash, or <code>-D_DEBUG_NEW_PROGNAME=\"a.exe\"</code> in the
|
||||
* Windows command prompt.
|
||||
*/
|
||||
#ifndef _DEBUG_NEW_PROGNAME
|
||||
#define _DEBUG_NEW_PROGNAME NULL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def _DEBUG_NEW_STD_OPER_NEW
|
||||
*
|
||||
* Macro to indicate whether the standard-conformant behaviour of
|
||||
* <code>operator new</code> is wanted. It is on by default now, but
|
||||
* the user may set it to \c 0 to revert to the old behaviour.
|
||||
*/
|
||||
#ifndef _DEBUG_NEW_STD_OPER_NEW
|
||||
#define _DEBUG_NEW_STD_OPER_NEW 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def _DEBUG_NEW_TAILCHECK
|
||||
*
|
||||
* Macro to indicate whether a writing-past-end check will be performed.
|
||||
* Define it to a positive integer as the number of padding bytes at the
|
||||
* end of a memory block for checking.
|
||||
*/
|
||||
#ifndef _DEBUG_NEW_TAILCHECK
|
||||
#define _DEBUG_NEW_TAILCHECK 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def _DEBUG_NEW_TAILCHECK_CHAR
|
||||
*
|
||||
* Value of the padding bytes at the end of a memory block.
|
||||
*/
|
||||
#ifndef _DEBUG_NEW_TAILCHECK_CHAR
|
||||
#define _DEBUG_NEW_TAILCHECK_CHAR 0xCC
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def _DEBUG_NEW_USE_ADDR2LINE
|
||||
*
|
||||
* Whether to use \e addr2line to convert a caller address to file/line
|
||||
* information. Defining it to a non-zero value will enable the
|
||||
* conversion (automatically done if GCC is detected). Defining it to
|
||||
* zero will disable the conversion.
|
||||
*/
|
||||
#ifndef _DEBUG_NEW_USE_ADDR2LINE
|
||||
#ifdef __GNUC__
|
||||
#define _DEBUG_NEW_USE_ADDR2LINE 1
|
||||
#else
|
||||
#define _DEBUG_NEW_USE_ADDR2LINE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4073) // #pragma init_seg(lib) used
|
||||
#pragma warning(disable: 4290) // C++ exception specification ignored
|
||||
#pragma init_seg(lib)
|
||||
#endif
|
||||
|
||||
#undef _DEBUG_NEW_EMULATE_MALLOC
|
||||
#undef _DEBUG_NEW_REDEFINE_NEW
|
||||
/**
|
||||
* Macro to indicate whether redefinition of \c new is wanted. Here it
|
||||
* is defined to \c 0 to disable the redefinition of \c new.
|
||||
*/
|
||||
#define _DEBUG_NEW_REDEFINE_NEW 0
|
||||
#include "debug_new.h"
|
||||
|
||||
/**
|
||||
* Gets the aligned value of memory block size.
|
||||
*/
|
||||
#define align(s) \
|
||||
(((s) + _DEBUG_NEW_ALIGNMENT - 1) & ~(_DEBUG_NEW_ALIGNMENT - 1))
|
||||
|
||||
/**
|
||||
* Structure to store the position information where \c new occurs.
|
||||
*/
|
||||
struct new_ptr_list_t
|
||||
{
|
||||
new_ptr_list_t* next;
|
||||
new_ptr_list_t* prev;
|
||||
size_t size;
|
||||
union
|
||||
{
|
||||
#if _DEBUG_NEW_FILENAME_LEN == 0
|
||||
const char* file;
|
||||
#else
|
||||
char file[_DEBUG_NEW_FILENAME_LEN];
|
||||
#endif
|
||||
void* addr;
|
||||
};
|
||||
unsigned line :31;
|
||||
unsigned is_array :1;
|
||||
unsigned magic;
|
||||
};
|
||||
|
||||
/**
|
||||
* Magic number for error detection.
|
||||
*/
|
||||
const unsigned MAGIC = 0x4442474E;
|
||||
|
||||
/**
|
||||
* The extra memory allocated by <code>operator new</code>.
|
||||
*/
|
||||
const int ALIGNED_LIST_ITEM_SIZE = align(sizeof(new_ptr_list_t));
|
||||
|
||||
/**
|
||||
* List of all new'd pointers.
|
||||
*/
|
||||
static new_ptr_list_t new_ptr_list = {
|
||||
&new_ptr_list,
|
||||
&new_ptr_list,
|
||||
0,
|
||||
{
|
||||
#if _DEBUG_NEW_FILENAME_LEN == 0
|
||||
NULL
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
},
|
||||
0,
|
||||
0,
|
||||
MAGIC
|
||||
};
|
||||
|
||||
/**
|
||||
* The mutex guard to protect simultaneous access to the pointer list.
|
||||
*/
|
||||
static fast_mutex new_ptr_lock;
|
||||
|
||||
/**
|
||||
* The mutex guard to protect simultaneous output to #new_output_fp.
|
||||
*/
|
||||
static fast_mutex new_output_lock;
|
||||
|
||||
/**
|
||||
* Total memory allocated in bytes.
|
||||
*/
|
||||
static size_t total_mem_alloc = 0;
|
||||
|
||||
/**
|
||||
* Flag to control whether #check_leaks will be automatically called on
|
||||
* program exit.
|
||||
*/
|
||||
bool new_autocheck_flag = true;
|
||||
|
||||
/**
|
||||
* Flag to control whether verbose messages are output.
|
||||
*/
|
||||
bool new_verbose_flag = false;
|
||||
|
||||
/**
|
||||
* Pointer to the output stream. The default output is \e stderr, and
|
||||
* one may change it to a user stream if needed (say, #new_verbose_flag
|
||||
* is \c true and there are a lot of (de)allocations).
|
||||
*/
|
||||
FILE* new_output_fp = stderr;
|
||||
|
||||
/**
|
||||
* Pointer to the program name. Its initial value is the macro
|
||||
* #_DEBUG_NEW_PROGNAME. You should try to assign the program path to
|
||||
* it early in your application. Assigning <code>argv[0]</code> to it
|
||||
* in \e main is one way. If you use \e bash or \e ksh (or similar),
|
||||
* the following statement is probably what you want:
|
||||
* `<code>new_progname = getenv("_");</code>'.
|
||||
*/
|
||||
const char* new_progname = _DEBUG_NEW_PROGNAME;
|
||||
|
||||
#if _DEBUG_NEW_USE_ADDR2LINE
|
||||
/**
|
||||
* Tries printing the position information from an instruction address.
|
||||
* This is the version that uses \e addr2line.
|
||||
*
|
||||
* @param addr the instruction address to convert and print
|
||||
* @return \c true if the address is converted successfully (and
|
||||
* the result is printed); \c false if no useful
|
||||
* information is got (and nothing is printed)
|
||||
*/
|
||||
static bool print_position_from_addr(const void* addr)
|
||||
{
|
||||
static const void* last_addr = NULL;
|
||||
static char last_info[256] = "";
|
||||
if (addr == last_addr)
|
||||
{
|
||||
if (last_info[0] == '\0')
|
||||
return false;
|
||||
fprintf(new_output_fp, "%s", last_info);
|
||||
return true;
|
||||
}
|
||||
if (new_progname)
|
||||
{
|
||||
const char addr2line_cmd[] = "addr2line -e ";
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
const int exeext_len = 4;
|
||||
#else
|
||||
const int exeext_len = 0;
|
||||
#endif
|
||||
#if !defined(__CYGWIN__) && defined(__unix__)
|
||||
const char ignore_err[] = " 2>/dev/null";
|
||||
#elif defined(__CYGWIN__) || \
|
||||
(defined(_WIN32) && defined(WINVER) && WINVER >= 0x0500)
|
||||
const char ignore_err[] = " 2>nul";
|
||||
#else
|
||||
const char ignore_err[] = "";
|
||||
#endif
|
||||
char* cmd = (char*)alloca(strlen(new_progname)
|
||||
+ exeext_len
|
||||
+ sizeof addr2line_cmd - 1
|
||||
+ sizeof ignore_err - 1
|
||||
+ sizeof(void*) * 2
|
||||
+ 4 /* SP + "0x" + null */);
|
||||
strcpy(cmd, addr2line_cmd);
|
||||
strcpy(cmd + sizeof addr2line_cmd - 1, new_progname);
|
||||
size_t len = strlen(cmd);
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
if (len <= 4
|
||||
|| (strcmp(cmd + len - 4, ".exe") != 0 &&
|
||||
strcmp(cmd + len - 4, ".EXE") != 0))
|
||||
{
|
||||
strcpy(cmd + len, ".exe");
|
||||
len += 4;
|
||||
}
|
||||
#endif
|
||||
sprintf(cmd + len, " %p%s", addr, ignore_err);
|
||||
FILE* fp = popen(cmd, "r");
|
||||
if (fp)
|
||||
{
|
||||
char buffer[sizeof last_info] = "";
|
||||
len = 0;
|
||||
if (fgets(buffer, sizeof buffer, fp))
|
||||
{
|
||||
len = strlen(buffer);
|
||||
if (buffer[len - 1] == '\n')
|
||||
buffer[--len] = '\0';
|
||||
}
|
||||
int res = pclose(fp);
|
||||
// Display the file/line information only if the command
|
||||
// is executed successfully and the output points to a
|
||||
// valid position, but the result will be cached if only
|
||||
// the command is executed successfully.
|
||||
if (res == 0 && len > 0)
|
||||
{
|
||||
last_addr = addr;
|
||||
if (buffer[len - 1] == '0' && buffer[len - 2] == ':')
|
||||
last_info[0] = '\0';
|
||||
else
|
||||
{
|
||||
fprintf(new_output_fp, "%s", buffer);
|
||||
strcpy(last_info, buffer);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* Tries printing the position information from an instruction address.
|
||||
* This is the stub version that does nothing at all.
|
||||
*
|
||||
* @return \c false always
|
||||
*/
|
||||
static bool print_position_from_addr(const void*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif // _DEBUG_NEW_USE_ADDR2LINE
|
||||
|
||||
/**
|
||||
* Prints the position information of a memory operation point. When \c
|
||||
* _DEBUG_NEW_USE_ADDR2LINE is defined to a non-zero value, this
|
||||
* function will try to convert a given caller address to file/line
|
||||
* information with \e addr2line.
|
||||
*
|
||||
* @param ptr source file name if \e line is non-zero; caller address
|
||||
* otherwise
|
||||
* @param line source line number if non-zero; indication that \e ptr
|
||||
* is the caller address otherwise
|
||||
*/
|
||||
static void print_position(const void* ptr, int line)
|
||||
{
|
||||
if (line != 0) // Is file/line information present?
|
||||
{
|
||||
fprintf(new_output_fp, "%s:%d", (const char*)ptr, line);
|
||||
}
|
||||
else if (ptr != NULL) // Is caller address present?
|
||||
{
|
||||
if (!print_position_from_addr(ptr)) // Fail to get source position?
|
||||
fprintf(new_output_fp, "%p", ptr);
|
||||
}
|
||||
else // No information is present
|
||||
{
|
||||
fprintf(new_output_fp, "<Unknown>");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the padding bytes at the end of a memory block is
|
||||
* tampered with.
|
||||
*
|
||||
* @param ptr pointer to a new_ptr_list_t struct
|
||||
* @return \c true if the padding bytes are untouched; \c false
|
||||
* otherwise
|
||||
*/
|
||||
static bool check_tail(new_ptr_list_t* ptr)
|
||||
{
|
||||
const unsigned char* const pointer = (unsigned char*)ptr +
|
||||
ALIGNED_LIST_ITEM_SIZE + ptr->size;
|
||||
for (int i = 0; i < _DEBUG_NEW_TAILCHECK; ++i)
|
||||
if (pointer[i] != _DEBUG_NEW_TAILCHECK_CHAR)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates memory and initializes control data.
|
||||
*
|
||||
* @param size size of the required memory block
|
||||
* @param file null-terminated string of the file name
|
||||
* @param line line number
|
||||
* @param is_array boolean value whether this is an array operation
|
||||
* @return pointer to the user-requested memory area; \c NULL
|
||||
* if memory allocation is not successful
|
||||
*/
|
||||
static void* alloc_mem(size_t size, const char* file, int line, bool is_array)
|
||||
{
|
||||
assert(line >= 0);
|
||||
STATIC_ASSERT((_DEBUG_NEW_ALIGNMENT & (_DEBUG_NEW_ALIGNMENT - 1)) == 0,
|
||||
Alignment_must_be_power_of_two);
|
||||
STATIC_ASSERT(_DEBUG_NEW_TAILCHECK >= 0, Invalid_tail_check_length);
|
||||
size_t s = size + ALIGNED_LIST_ITEM_SIZE + _DEBUG_NEW_TAILCHECK;
|
||||
new_ptr_list_t* ptr = (new_ptr_list_t*)malloc(s);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
#if _DEBUG_NEW_STD_OPER_NEW
|
||||
return NULL;
|
||||
#else
|
||||
fast_mutex_autolock lock(new_output_lock);
|
||||
fprintf(new_output_fp,
|
||||
"Out of memory when allocating %u bytes\n",
|
||||
size);
|
||||
fflush(new_output_fp);
|
||||
_DEBUG_NEW_ERROR_ACTION;
|
||||
#endif
|
||||
}
|
||||
void* pointer = (char*)ptr + ALIGNED_LIST_ITEM_SIZE;
|
||||
#if _DEBUG_NEW_FILENAME_LEN == 0
|
||||
ptr->file = file;
|
||||
#else
|
||||
if (line)
|
||||
strncpy(ptr->file, file, _DEBUG_NEW_FILENAME_LEN - 1)
|
||||
[_DEBUG_NEW_FILENAME_LEN - 1] = '\0';
|
||||
else
|
||||
ptr->addr = (void*)file;
|
||||
#endif
|
||||
ptr->line = line;
|
||||
ptr->is_array = is_array;
|
||||
ptr->size = size;
|
||||
ptr->magic = MAGIC;
|
||||
{
|
||||
fast_mutex_autolock lock(new_ptr_lock);
|
||||
ptr->prev = new_ptr_list.prev;
|
||||
ptr->next = &new_ptr_list;
|
||||
new_ptr_list.prev->next = ptr;
|
||||
new_ptr_list.prev = ptr;
|
||||
}
|
||||
#if _DEBUG_NEW_TAILCHECK
|
||||
memset((char*)pointer + size, _DEBUG_NEW_TAILCHECK_CHAR,
|
||||
_DEBUG_NEW_TAILCHECK);
|
||||
#endif
|
||||
if (new_verbose_flag)
|
||||
{
|
||||
fast_mutex_autolock lock(new_output_lock);
|
||||
fprintf(new_output_fp,
|
||||
"new%s: allocated %p (size %u, ",
|
||||
is_array ? "[]" : "",
|
||||
pointer, size);
|
||||
if (line != 0)
|
||||
print_position(ptr->file, ptr->line);
|
||||
else
|
||||
print_position(ptr->addr, ptr->line);
|
||||
fprintf(new_output_fp, ")\n");
|
||||
}
|
||||
total_mem_alloc += size;
|
||||
return pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees memory and adjusts pointers.
|
||||
*
|
||||
* @param pointer pointer to delete
|
||||
* @param addr pointer to the caller
|
||||
* @param is_array flag indicating whether it is invoked by a
|
||||
* <code>delete[]</code> call
|
||||
*/
|
||||
static void free_pointer(void* pointer, void* addr, bool is_array)
|
||||
{
|
||||
if (pointer == NULL)
|
||||
return;
|
||||
new_ptr_list_t* ptr =
|
||||
(new_ptr_list_t*)((char*)pointer - ALIGNED_LIST_ITEM_SIZE);
|
||||
if (ptr->magic != MAGIC)
|
||||
{
|
||||
{
|
||||
fast_mutex_autolock lock(new_output_lock);
|
||||
fprintf(new_output_fp, "delete%s: invalid pointer %p (",
|
||||
is_array ? "[]" : "", pointer);
|
||||
print_position(_DEBUG_NEW_CALLER_ADDRESS, 0);
|
||||
fprintf(new_output_fp, ")\n");
|
||||
}
|
||||
check_mem_corruption();
|
||||
fflush(new_output_fp);
|
||||
_DEBUG_NEW_ERROR_ACTION;
|
||||
}
|
||||
if (is_array != ptr->is_array)
|
||||
{
|
||||
const char* msg;
|
||||
if (is_array)
|
||||
msg = "delete[] after new";
|
||||
else
|
||||
msg = "delete after new[]";
|
||||
fast_mutex_autolock lock(new_output_lock);
|
||||
fprintf(new_output_fp,
|
||||
"%s: pointer %p (size %u)\n\tat ",
|
||||
msg,
|
||||
(char*)ptr + ALIGNED_LIST_ITEM_SIZE,
|
||||
ptr->size);
|
||||
print_position(addr, 0);
|
||||
fprintf(new_output_fp, "\n\toriginally allocated at ");
|
||||
if (ptr->line != 0)
|
||||
print_position(ptr->file, ptr->line);
|
||||
else
|
||||
print_position(ptr->addr, ptr->line);
|
||||
fprintf(new_output_fp, "\n");
|
||||
fflush(new_output_fp);
|
||||
_DEBUG_NEW_ERROR_ACTION;
|
||||
}
|
||||
#if _DEBUG_NEW_TAILCHECK
|
||||
if (!check_tail(ptr))
|
||||
{
|
||||
check_mem_corruption();
|
||||
fflush(new_output_fp);
|
||||
_DEBUG_NEW_ERROR_ACTION;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
fast_mutex_autolock lock(new_ptr_lock);
|
||||
total_mem_alloc -= ptr->size;
|
||||
ptr->magic = 0;
|
||||
ptr->prev->next = ptr->next;
|
||||
ptr->next->prev = ptr->prev;
|
||||
}
|
||||
free(ptr);
|
||||
if (new_verbose_flag)
|
||||
{
|
||||
fast_mutex_autolock lock(new_output_lock);
|
||||
fprintf(new_output_fp,
|
||||
"delete%s: freed %p (size %u, %u bytes still allocated)\n",
|
||||
is_array ? "[]" : "",
|
||||
(char*)ptr + ALIGNED_LIST_ITEM_SIZE,
|
||||
ptr->size, total_mem_alloc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for memory leaks.
|
||||
*
|
||||
* @return zero if no leakage is found; the number of leaks otherwise
|
||||
*/
|
||||
int check_leaks()
|
||||
{
|
||||
int leak_cnt = 0;
|
||||
fast_mutex_autolock lock_ptr(new_ptr_lock);
|
||||
fast_mutex_autolock lock_output(new_output_lock);
|
||||
new_ptr_list_t* ptr = new_ptr_list.next;
|
||||
while (ptr != &new_ptr_list)
|
||||
{
|
||||
const char* const pointer = (char*)ptr + ALIGNED_LIST_ITEM_SIZE;
|
||||
if (ptr->magic != MAGIC)
|
||||
{
|
||||
fprintf(new_output_fp,
|
||||
"warning: heap data corrupt near %p\n",
|
||||
pointer);
|
||||
}
|
||||
#if _DEBUG_NEW_TAILCHECK
|
||||
if (!check_tail(ptr))
|
||||
{
|
||||
fprintf(new_output_fp,
|
||||
"warning: overwritten past end of object at %p\n",
|
||||
pointer);
|
||||
}
|
||||
#endif
|
||||
fprintf(new_output_fp,
|
||||
"Leaked object at %p (size %u, ",
|
||||
pointer,
|
||||
ptr->size);
|
||||
if (ptr->line != 0)
|
||||
print_position(ptr->file, ptr->line);
|
||||
else
|
||||
print_position(ptr->addr, ptr->line);
|
||||
fprintf(new_output_fp, ")\n");
|
||||
ptr = ptr->next;
|
||||
++leak_cnt;
|
||||
}
|
||||
if (new_verbose_flag || leak_cnt)
|
||||
fprintf(new_output_fp, "*** %d leaks found\n", leak_cnt);
|
||||
return leak_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for heap corruption.
|
||||
*
|
||||
* @return zero if no problem is found; the number of found memory
|
||||
* corruptions otherwise
|
||||
*/
|
||||
int check_mem_corruption()
|
||||
{
|
||||
int corrupt_cnt = 0;
|
||||
fast_mutex_autolock lock_ptr(new_ptr_lock);
|
||||
fast_mutex_autolock lock_output(new_output_lock);
|
||||
fprintf(new_output_fp, "*** Checking for memory corruption: START\n");
|
||||
for (new_ptr_list_t* ptr = new_ptr_list.next;
|
||||
ptr != &new_ptr_list;
|
||||
ptr = ptr->next)
|
||||
{
|
||||
const char* const pointer = (char*)ptr + ALIGNED_LIST_ITEM_SIZE;
|
||||
if (ptr->magic == MAGIC
|
||||
#if _DEBUG_NEW_TAILCHECK
|
||||
&& check_tail(ptr)
|
||||
#endif
|
||||
)
|
||||
continue;
|
||||
#if _DEBUG_NEW_TAILCHECK
|
||||
if (ptr->magic != MAGIC)
|
||||
{
|
||||
#endif
|
||||
fprintf(new_output_fp,
|
||||
"Heap data corrupt near %p (size %u, ",
|
||||
pointer,
|
||||
ptr->size);
|
||||
#if _DEBUG_NEW_TAILCHECK
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(new_output_fp,
|
||||
"Overwritten past end of object at %p (size %u, ",
|
||||
pointer,
|
||||
ptr->size);
|
||||
}
|
||||
#endif
|
||||
if (ptr->line != 0)
|
||||
print_position(ptr->file, ptr->line);
|
||||
else
|
||||
print_position(ptr->addr, ptr->line);
|
||||
fprintf(new_output_fp, ")\n");
|
||||
++corrupt_cnt;
|
||||
}
|
||||
fprintf(new_output_fp, "*** Checking for memory corruption: %d FOUND\n",
|
||||
corrupt_cnt);
|
||||
return corrupt_cnt;
|
||||
}
|
||||
|
||||
void __debug_new_recorder::_M_process(void* pointer)
|
||||
{
|
||||
if (pointer == NULL)
|
||||
return;
|
||||
new_ptr_list_t* ptr =
|
||||
(new_ptr_list_t*)((char*)pointer - ALIGNED_LIST_ITEM_SIZE);
|
||||
if (ptr->magic != MAGIC || ptr->line != 0)
|
||||
{
|
||||
fast_mutex_autolock lock(new_output_lock);
|
||||
fprintf(new_output_fp,
|
||||
"warning: debug_new used with placement new (%s:%d)\n",
|
||||
_M_file, _M_line);
|
||||
return;
|
||||
}
|
||||
#if _DEBUG_NEW_FILENAME_LEN == 0
|
||||
ptr->file = _M_file;
|
||||
#else
|
||||
strncpy(ptr->file, _M_file, _DEBUG_NEW_FILENAME_LEN - 1)
|
||||
[_DEBUG_NEW_FILENAME_LEN - 1] = '\0';
|
||||
#endif
|
||||
ptr->line = _M_line;
|
||||
}
|
||||
|
||||
void* operator new(size_t size, const char* file, int line)
|
||||
{
|
||||
void* ptr = alloc_mem(size, file, line, false);
|
||||
#if _DEBUG_NEW_STD_OPER_NEW
|
||||
if (ptr)
|
||||
return ptr;
|
||||
else
|
||||
throw std::bad_alloc();
|
||||
#else
|
||||
return ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void* operator new[](size_t size, const char* file, int line)
|
||||
{
|
||||
void* ptr = alloc_mem(size, file, line, true);
|
||||
#if _DEBUG_NEW_STD_OPER_NEW
|
||||
if (ptr)
|
||||
return ptr;
|
||||
else
|
||||
throw std::bad_alloc();
|
||||
#else
|
||||
return ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void* operator new(size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
return operator new(size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0);
|
||||
}
|
||||
|
||||
void* operator new[](size_t size) throw(std::bad_alloc)
|
||||
{
|
||||
return operator new[](size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0);
|
||||
}
|
||||
|
||||
#if !defined(__BORLANDC__) || __BORLANDC__ > 0x551
|
||||
void* operator new(size_t size, const std::nothrow_t&) throw()
|
||||
{
|
||||
return alloc_mem(size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0, false);
|
||||
}
|
||||
|
||||
void* operator new[](size_t size, const std::nothrow_t&) throw()
|
||||
{
|
||||
return alloc_mem(size, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
void operator delete(void* pointer) throw()
|
||||
{
|
||||
free_pointer(pointer, _DEBUG_NEW_CALLER_ADDRESS, false);
|
||||
}
|
||||
|
||||
void operator delete[](void* pointer) throw()
|
||||
{
|
||||
free_pointer(pointer, _DEBUG_NEW_CALLER_ADDRESS, true);
|
||||
}
|
||||
|
||||
#if HAVE_PLACEMENT_DELETE
|
||||
void operator delete(void* pointer, const char* file, int line) throw()
|
||||
{
|
||||
if (new_verbose_flag)
|
||||
{
|
||||
fast_mutex_autolock lock(new_output_lock);
|
||||
fprintf(new_output_fp,
|
||||
"info: exception thrown on initializing object at %p (",
|
||||
pointer);
|
||||
print_position(file, line);
|
||||
fprintf(new_output_fp, ")\n");
|
||||
}
|
||||
operator delete(pointer);
|
||||
}
|
||||
|
||||
void operator delete[](void* pointer, const char* file, int line) throw()
|
||||
{
|
||||
if (new_verbose_flag)
|
||||
{
|
||||
fast_mutex_autolock lock(new_output_lock);
|
||||
fprintf(new_output_fp,
|
||||
"info: exception thrown on initializing objects at %p (",
|
||||
pointer);
|
||||
print_position(file, line);
|
||||
fprintf(new_output_fp, ")\n");
|
||||
}
|
||||
operator delete[](pointer);
|
||||
}
|
||||
|
||||
void operator delete(void* pointer, const std::nothrow_t&) throw()
|
||||
{
|
||||
operator delete(pointer, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0);
|
||||
}
|
||||
|
||||
void operator delete[](void* pointer, const std::nothrow_t&) throw()
|
||||
{
|
||||
operator delete[](pointer, (char*)_DEBUG_NEW_CALLER_ADDRESS, 0);
|
||||
}
|
||||
#endif // HAVE_PLACEMENT_DELETE
|
||||
|
||||
int __debug_new_counter::_S_count = 0;
|
||||
|
||||
/**
|
||||
* Constructor to increment the count.
|
||||
*/
|
||||
__debug_new_counter::__debug_new_counter()
|
||||
{
|
||||
++_S_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor to decrement the count. When the count is zero,
|
||||
* #check_leaks will be called.
|
||||
*/
|
||||
__debug_new_counter::~__debug_new_counter()
|
||||
{
|
||||
if (--_S_count == 0 && new_autocheck_flag)
|
||||
if (check_leaks())
|
||||
{
|
||||
new_verbose_flag = true;
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
if (!getenv("GLIBCPP_FORCE_NEW") && !getenv("GLIBCXX_FORCE_NEW"))
|
||||
fprintf(new_output_fp,
|
||||
"*** WARNING: GCC 3 or later is detected, please make sure the\n"
|
||||
" environment variable GLIBCPP_FORCE_NEW (GCC 3.2 and 3.3) or\n"
|
||||
" GLIBCXX_FORCE_NEW (GCC 3.4 and later) is defined. Check the\n"
|
||||
" README file for details.\n");
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||
// vim:tabstop=4:shiftwidth=4:expandtab:
|
||||
|
||||
/*
|
||||
* Copyright (C) 2004-2007 Wu Yongwei <adah at users dot sourceforge dot net>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute
|
||||
* it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must
|
||||
* not claim that you wrote the original software. If you use this
|
||||
* software in a product, an acknowledgement in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must
|
||||
* not be misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* This file is part of Stones of Nvwa:
|
||||
* http://sourceforge.net/projects/nvwa
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file debug_new.h
|
||||
*
|
||||
* Header file for checking leaks caused by unmatched new/delete.
|
||||
*
|
||||
* @version 4.4, 2007/12/31
|
||||
* @author Wu Yongwei
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DEBUG_NEW_H
|
||||
#define _DEBUG_NEW_H
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* @def HAVE_PLACEMENT_DELETE
|
||||
*
|
||||
* Macro to indicate whether placement delete operators are supported on
|
||||
* a certain compiler. Some compilers, like Borland C++ Compiler 5.5.1
|
||||
* and Digital Mars Compiler 8.42, do not support them, and the user
|
||||
* must define this macro to \c 0 to make the program compile. Also
|
||||
* note that in that case memory leakage will occur if an exception is
|
||||
* thrown in the initialization (constructor) of a dynamically created
|
||||
* object.
|
||||
*/
|
||||
#ifndef HAVE_PLACEMENT_DELETE
|
||||
#define HAVE_PLACEMENT_DELETE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def _DEBUG_NEW_REDEFINE_NEW
|
||||
*
|
||||
* Macro to indicate whether redefinition of \c new is wanted. If one
|
||||
* wants to define one's own <code>operator new</code>, to call
|
||||
* <code>operator new</code> directly, or to call placement \c new, it
|
||||
* should be defined to \c 0 to alter the default behaviour. Unless, of
|
||||
* course, one is willing to take the trouble to write something like:
|
||||
* @code
|
||||
* # ifdef new
|
||||
* # define _NEW_REDEFINED
|
||||
* # undef new
|
||||
* # endif
|
||||
*
|
||||
* // Code that uses new is here
|
||||
*
|
||||
* # ifdef _NEW_REDEFINED
|
||||
* # ifdef DEBUG_NEW
|
||||
* # define new DEBUG_NEW
|
||||
* # endif
|
||||
* # undef _NEW_REDEFINED
|
||||
* # endif
|
||||
* @endcode
|
||||
*/
|
||||
#ifndef _DEBUG_NEW_REDEFINE_NEW
|
||||
#define _DEBUG_NEW_REDEFINE_NEW 1
|
||||
#endif
|
||||
|
||||
/* Prototypes */
|
||||
int check_leaks();
|
||||
int check_mem_corruption();
|
||||
void* operator new(size_t size, const char* file, int line);
|
||||
void* operator new[](size_t size, const char* file, int line);
|
||||
#if HAVE_PLACEMENT_DELETE
|
||||
void operator delete(void* pointer, const char* file, int line) throw();
|
||||
void operator delete[](void* pointer, const char* file, int line) throw();
|
||||
#endif
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||
// MSVC 6 requires the following declarations; or the non-placement
|
||||
// new[]/delete[] will not compile.
|
||||
void* operator new[](size_t) throw(std::bad_alloc);
|
||||
void operator delete[](void*) throw();
|
||||
#endif
|
||||
|
||||
/* Control variables */
|
||||
extern bool new_autocheck_flag; // default to true: call check_leaks() on exit
|
||||
extern bool new_verbose_flag; // default to false: no verbose information
|
||||
extern FILE* new_output_fp; // default to stderr: output to console
|
||||
extern const char* new_progname;// default to NULL; should be assigned argv[0]
|
||||
|
||||
/**
|
||||
* @def DEBUG_NEW
|
||||
*
|
||||
* Macro to catch file/line information on allocation. If
|
||||
* #_DEBUG_NEW_REDEFINE_NEW is \c 0, one can use this macro directly;
|
||||
* otherwise \c new will be defined to it, and one must use \c new
|
||||
* instead.
|
||||
*/
|
||||
#define DEBUG_NEW __debug_new_recorder(__FILE__, __LINE__) ->* new
|
||||
|
||||
# if _DEBUG_NEW_REDEFINE_NEW
|
||||
# define new DEBUG_NEW
|
||||
# endif
|
||||
# ifdef _DEBUG_NEW_EMULATE_MALLOC
|
||||
# include <stdlib.h>
|
||||
# ifdef new
|
||||
# define malloc(s) ((void*)(new char[s]))
|
||||
# else
|
||||
# define malloc(s) ((void*)(DEBUG_NEW char[s]))
|
||||
# endif
|
||||
# define free(p) delete[] (char*)(p)
|
||||
# endif
|
||||
|
||||
/**
|
||||
* Recorder class to remember the call context.
|
||||
*
|
||||
* The idea comes from <a href="http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/7089382e3bc1c489/85f9107a1dc79ee9?#85f9107a1dc79ee9">Greg Herlihy's post</a> in comp.lang.c++.moderated.
|
||||
*/
|
||||
class __debug_new_recorder
|
||||
{
|
||||
const char* _M_file;
|
||||
const int _M_line;
|
||||
void _M_process(void* pointer);
|
||||
public:
|
||||
/**
|
||||
* Constructor to remember the call context. The information will
|
||||
* be used in __debug_new_recorder::operator->*.
|
||||
*/
|
||||
__debug_new_recorder(const char* file, int line)
|
||||
: _M_file(file), _M_line(line) {}
|
||||
/**
|
||||
* Operator to write the context information to memory.
|
||||
* <code>operator->*</code> is chosen because it has the right
|
||||
* precedence, it is rarely used, and it looks good: so people can
|
||||
* tell the special usage more quickly.
|
||||
*/
|
||||
template <class _Tp> _Tp* operator->*(_Tp* pointer)
|
||||
{ _M_process(pointer); return pointer; }
|
||||
private:
|
||||
__debug_new_recorder(const __debug_new_recorder&);
|
||||
__debug_new_recorder& operator=(const __debug_new_recorder&);
|
||||
};
|
||||
|
||||
/**
|
||||
* Counter class for on-exit leakage check.
|
||||
*
|
||||
* This technique is learnt from <em>The C++ Programming Language</em> by
|
||||
* Bjarne Stroustup.
|
||||
*/
|
||||
class __debug_new_counter
|
||||
{
|
||||
static int _S_count;
|
||||
public:
|
||||
__debug_new_counter();
|
||||
~__debug_new_counter();
|
||||
};
|
||||
/** Counting object for each file including debug_new.h. */
|
||||
static __debug_new_counter __debug_new_count;
|
||||
|
||||
#endif // _DEBUG_NEW_H
|
|
@ -0,0 +1,311 @@
|
|||
// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||
// vim:tabstop=4:shiftwidth=4:expandtab:
|
||||
|
||||
/*
|
||||
* Copyright (C) 2004-2007 Wu Yongwei <adah at users dot sourceforge dot net>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute
|
||||
* it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must
|
||||
* not claim that you wrote the original software. If you use this
|
||||
* software in a product, an acknowledgement in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must
|
||||
* not be misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* This file is part of Stones of Nvwa:
|
||||
* http://sourceforge.net/projects/nvwa
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fast_mutex.h
|
||||
*
|
||||
* A fast mutex implementation for POSIX and Win32.
|
||||
*
|
||||
* @version 1.18, 2005/05/06
|
||||
* @author Wu Yongwei
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _FAST_MUTEX_H
|
||||
#define _FAST_MUTEX_H
|
||||
|
||||
# if !defined(_NOTHREADS)
|
||||
# if !defined(_WIN32THREADS) && \
|
||||
(defined(_WIN32) && defined(_MT))
|
||||
// Automatically use _WIN32THREADS when specifying -MT/-MD in MSVC,
|
||||
// or -mthreads in MinGW GCC.
|
||||
# define _WIN32THREADS
|
||||
# elif !defined(_PTHREADS) && \
|
||||
defined(_REENTRANT)
|
||||
// Automatically use _PTHREADS when specifying -pthread in GCC.
|
||||
// N.B. I do not detect on _PTHREAD_H since libstdc++-v3 under
|
||||
// Linux will silently include <pthread.h> anyway.
|
||||
# define _PTHREADS
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_PTHREADS) && !defined(_WIN32THREADS) && !defined(_NOTHREADS)
|
||||
# define _NOTHREADS
|
||||
# endif
|
||||
|
||||
# if defined(_NOTHREADS)
|
||||
# if defined(_PTHREADS) || defined(_WIN32THREADS)
|
||||
# undef _NOTHREADS
|
||||
# error "Cannot define multi-threaded mode with -D_NOTHREADS"
|
||||
# if defined(__MINGW32__) && defined(_WIN32THREADS) && !defined(_MT)
|
||||
# error "Be sure to specify -mthreads with -D_WIN32THREADS"
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
/**
|
||||
* Macro to control whether to check for initialization status for each
|
||||
* lock/unlock operation. Defining it to a non-zero value will enable
|
||||
* the check, so that the construction/destruction of a static object
|
||||
* using a static fast_mutex not yet constructed or already destroyed
|
||||
* will work (with lock/unlock operations ignored). Defining it to zero
|
||||
* will disable to check.
|
||||
*/
|
||||
# define _FAST_MUTEX_CHECK_INITIALIZATION 1
|
||||
# endif
|
||||
|
||||
# if defined(_PTHREADS) && defined(_WIN32THREADS)
|
||||
// Some C++ libraries have _PTHREADS defined even on Win32 platforms.
|
||||
// Thus this hack.
|
||||
# undef _PTHREADS
|
||||
# endif
|
||||
|
||||
# ifdef _DEBUG
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
/** Macro for fast_mutex assertions. Real version (for debug mode). */
|
||||
# define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
|
||||
if (!(_Expr)) { \
|
||||
fprintf(stderr, "fast_mutex::%s\n", _Msg); \
|
||||
abort(); \
|
||||
}
|
||||
# else
|
||||
/** Macro for fast_mutex assertions. Fake version (for release mode). */
|
||||
# define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
|
||||
((void)0)
|
||||
# endif
|
||||
|
||||
# ifdef _PTHREADS
|
||||
# include <pthread.h>
|
||||
/**
|
||||
* Macro alias to `volatile' semantics. Here it is truly volatile since
|
||||
* it is in a multi-threaded (POSIX threads) environment.
|
||||
*/
|
||||
# define __VOLATILE volatile
|
||||
/**
|
||||
* Class for non-reentrant fast mutexes. This is the implementation
|
||||
* for POSIX threads.
|
||||
*/
|
||||
class fast_mutex
|
||||
{
|
||||
pthread_mutex_t _M_mtx_impl;
|
||||
# if _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
bool _M_initialized;
|
||||
# endif
|
||||
# ifdef _DEBUG
|
||||
bool _M_locked;
|
||||
# endif
|
||||
public:
|
||||
fast_mutex()
|
||||
# ifdef _DEBUG
|
||||
: _M_locked(false)
|
||||
# endif
|
||||
{
|
||||
::pthread_mutex_init(&_M_mtx_impl, NULL);
|
||||
# if _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
_M_initialized = true;
|
||||
# endif
|
||||
}
|
||||
~fast_mutex()
|
||||
{
|
||||
_FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
|
||||
# if _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
_M_initialized = false;
|
||||
# endif
|
||||
::pthread_mutex_destroy(&_M_mtx_impl);
|
||||
}
|
||||
void lock()
|
||||
{
|
||||
# if _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
if (!_M_initialized)
|
||||
return;
|
||||
# endif
|
||||
::pthread_mutex_lock(&_M_mtx_impl);
|
||||
# ifdef _DEBUG
|
||||
// The following assertion should _always_ be true for a
|
||||
// real `fast' pthread_mutex. However, this assertion can
|
||||
// help sometimes, when people forget to use `-lpthread' and
|
||||
// glibc provides an empty implementation. Having this
|
||||
// assertion is also more consistent.
|
||||
_FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
|
||||
_M_locked = true;
|
||||
# endif
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
# if _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
if (!_M_initialized)
|
||||
return;
|
||||
# endif
|
||||
# ifdef _DEBUG
|
||||
_FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
|
||||
_M_locked = false;
|
||||
# endif
|
||||
::pthread_mutex_unlock(&_M_mtx_impl);
|
||||
}
|
||||
private:
|
||||
fast_mutex(const fast_mutex&);
|
||||
fast_mutex& operator=(const fast_mutex&);
|
||||
};
|
||||
# endif // _PTHREADS
|
||||
|
||||
# ifdef _WIN32THREADS
|
||||
# include <windows.h>
|
||||
/**
|
||||
* Macro alias to `volatile' semantics. Here it is truly volatile since
|
||||
* it is in a multi-threaded (Win32 threads) environment.
|
||||
*/
|
||||
# define __VOLATILE volatile
|
||||
/**
|
||||
* Class for non-reentrant fast mutexes. This is the implementation
|
||||
* for Win32 threads.
|
||||
*/
|
||||
class fast_mutex
|
||||
{
|
||||
CRITICAL_SECTION _M_mtx_impl;
|
||||
# if _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
bool _M_initialized;
|
||||
# endif
|
||||
# ifdef _DEBUG
|
||||
bool _M_locked;
|
||||
# endif
|
||||
public:
|
||||
fast_mutex()
|
||||
# ifdef _DEBUG
|
||||
: _M_locked(false)
|
||||
# endif
|
||||
{
|
||||
::InitializeCriticalSection(&_M_mtx_impl);
|
||||
# if _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
_M_initialized = true;
|
||||
# endif
|
||||
}
|
||||
~fast_mutex()
|
||||
{
|
||||
_FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
|
||||
# if _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
_M_initialized = false;
|
||||
# endif
|
||||
::DeleteCriticalSection(&_M_mtx_impl);
|
||||
}
|
||||
void lock()
|
||||
{
|
||||
# if _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
if (!_M_initialized)
|
||||
return;
|
||||
# endif
|
||||
::EnterCriticalSection(&_M_mtx_impl);
|
||||
# ifdef _DEBUG
|
||||
_FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
|
||||
_M_locked = true;
|
||||
# endif
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
# if _FAST_MUTEX_CHECK_INITIALIZATION
|
||||
if (!_M_initialized)
|
||||
return;
|
||||
# endif
|
||||
# ifdef _DEBUG
|
||||
_FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
|
||||
_M_locked = false;
|
||||
# endif
|
||||
::LeaveCriticalSection(&_M_mtx_impl);
|
||||
}
|
||||
private:
|
||||
fast_mutex(const fast_mutex&);
|
||||
fast_mutex& operator=(const fast_mutex&);
|
||||
};
|
||||
# endif // _WIN32THREADS
|
||||
|
||||
# ifdef _NOTHREADS
|
||||
/**
|
||||
* Macro alias to `volatile' semantics. Here it is not truly volatile
|
||||
* since it is in a single-threaded environment.
|
||||
*/
|
||||
# define __VOLATILE
|
||||
/**
|
||||
* Class for non-reentrant fast mutexes. This is the null
|
||||
* implementation for single-threaded environments.
|
||||
*/
|
||||
class fast_mutex
|
||||
{
|
||||
# ifdef _DEBUG
|
||||
bool _M_locked;
|
||||
# endif
|
||||
public:
|
||||
fast_mutex()
|
||||
# ifdef _DEBUG
|
||||
: _M_locked(false)
|
||||
# endif
|
||||
{
|
||||
}
|
||||
~fast_mutex()
|
||||
{
|
||||
_FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
|
||||
}
|
||||
void lock()
|
||||
{
|
||||
# ifdef _DEBUG
|
||||
_FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
|
||||
_M_locked = true;
|
||||
# endif
|
||||
}
|
||||
void unlock()
|
||||
{
|
||||
# ifdef _DEBUG
|
||||
_FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
|
||||
_M_locked = false;
|
||||
# endif
|
||||
}
|
||||
private:
|
||||
fast_mutex(const fast_mutex&);
|
||||
fast_mutex& operator=(const fast_mutex&);
|
||||
};
|
||||
# endif // _NOTHREADS
|
||||
|
||||
/** An acquistion-on-initialization lock class based on fast_mutex. */
|
||||
class fast_mutex_autolock
|
||||
{
|
||||
fast_mutex& _M_mtx;
|
||||
public:
|
||||
explicit fast_mutex_autolock(fast_mutex& __mtx) : _M_mtx(__mtx)
|
||||
{
|
||||
_M_mtx.lock();
|
||||
}
|
||||
~fast_mutex_autolock()
|
||||
{
|
||||
_M_mtx.unlock();
|
||||
}
|
||||
private:
|
||||
fast_mutex_autolock(const fast_mutex_autolock&);
|
||||
fast_mutex_autolock& operator=(const fast_mutex_autolock&);
|
||||
};
|
||||
|
||||
#endif // _FAST_MUTEX_H
|
File diff suppressed because it is too large
Load Diff
|
@ -22,6 +22,9 @@
|
|||
#include "pandora_windows_service.h"
|
||||
#include "ssh/pandora_ssh_test.h"
|
||||
#include "ftp/pandora_ftp_test.h"
|
||||
#ifdef __DEBUG__
|
||||
#include "debug_new.h"
|
||||
#endif
|
||||
|
||||
#define PATH_SIZE _MAX_PATH+1
|
||||
#define SERVICE_INSTALL_CMDLINE_PARAM "--install"
|
||||
|
|
|
@ -420,6 +420,7 @@ Pandora_Module::getXml () {
|
|||
delete element;
|
||||
|
||||
data_list_element->InsertEndChild (*data_element);
|
||||
delete data_element;
|
||||
}
|
||||
|
||||
root->InsertEndChild (*data_list_element);
|
||||
|
|
|
@ -341,9 +341,7 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
|||
} else if (module_inventory != "") {
|
||||
module = new Pandora_Module_Inventory (module_name, module_inventory);
|
||||
} else if (module_odbc != "") {
|
||||
module = new Pandora_Module_Odbc (module_name,
|
||||
module_odbc,
|
||||
module_odbc_query);
|
||||
module = new Pandora_Module_Odbc (module_name, module_odbc, module_odbc_query);
|
||||
} else if (module_logevent != "") {
|
||||
module = new Pandora_Module_Logevent (module_name,
|
||||
module_source,
|
||||
|
|
|
@ -377,6 +377,7 @@ Pandora_Module_Inventory::getXml() {
|
|||
delete element;
|
||||
|
||||
inventory_list_element->InsertEndChild (*data_element);
|
||||
delete data_element;
|
||||
}
|
||||
if (inventory_list_element != NULL)
|
||||
{
|
||||
|
|
|
@ -49,7 +49,7 @@ Pandora_Module_Regexp::Pandora_Module_Regexp (string name, string source, string
|
|||
// Open the file and skip to the end
|
||||
this->file.open (source.c_str ());
|
||||
if (this->file.is_open ()) {
|
||||
this->file.seekg (0, ios_base::end);
|
||||
//this->file.seekg (0, ios_base::end);
|
||||
} else {
|
||||
pandoraLog ("Error opening file %s", source.c_str ());
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ Pandora_Module_Regexp::Pandora_Module_Regexp (string name, string source, string
|
|||
* Pandora_Module_Regexp destructor.
|
||||
*/
|
||||
Pandora_Module_Regexp::~Pandora_Module_Regexp () {
|
||||
regfree (&this->regexp);
|
||||
this->file.close();
|
||||
}
|
||||
|
||||
|
@ -95,7 +96,7 @@ Pandora_Module_Regexp::run () {
|
|||
if (line.empty ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Try to match the line with the regexp
|
||||
if (regexec (&this->regexp, line.c_str (), 0, NULL, 0) == 0) {
|
||||
if (type == TYPE_GENERIC_DATA_STRING || type == TYPE_ASYNC_STRING) {
|
||||
|
|
|
@ -129,7 +129,7 @@ pandoraWriteLog (string filename, string line) {
|
|||
* @param ... Variable argument list
|
||||
*/
|
||||
void
|
||||
Pandora::pandoraLog (char *format, ...) {
|
||||
Pandora::pandoraLog (const char *format, ...) {
|
||||
va_list args;
|
||||
char msg[5000];
|
||||
|
||||
|
@ -150,7 +150,7 @@ Pandora::pandoraLog (char *format, ...) {
|
|||
* @param ... Variable argument list
|
||||
*/
|
||||
void
|
||||
Pandora::pandoraDebug (char *format, ...) {
|
||||
Pandora::pandoraDebug (const char *format, ...) {
|
||||
if (pandora_debug) {
|
||||
va_list args;
|
||||
char msg[5000];
|
||||
|
|
|
@ -76,8 +76,8 @@ namespace Pandora {
|
|||
bool getPandoraDebug ();
|
||||
string getPandoraAgentVersion ();
|
||||
|
||||
void pandoraDebug (char *format, ...);
|
||||
void pandoraLog (char *format, ...);
|
||||
void pandoraDebug (const char *format, ...);
|
||||
void pandoraLog (const char *format, ...);
|
||||
void pandoraFree (void * e);
|
||||
|
||||
bool is_enabled (string value);
|
||||
|
|
|
@ -38,7 +38,7 @@ using namespace Pandora;
|
|||
*/
|
||||
string
|
||||
Pandora_Strutils::trim (const string str) {
|
||||
char * delims = " \t\r\n";
|
||||
const char * delims = " \t\r\n";
|
||||
string result = str;
|
||||
string::size_type index = result.find_last_not_of (delims);
|
||||
|
||||
|
|
|
@ -69,16 +69,23 @@ Pandora_Windows_Service::setValues (const char * svc_name,
|
|||
this->interval = 60000;
|
||||
this->transfer_interval = this->interval;
|
||||
this->elapsed_transfer_time = 0;
|
||||
this->udp_server = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a Pandora_Windows_Service object.
|
||||
*/
|
||||
Pandora_Windows_Service::~Pandora_Windows_Service () {
|
||||
|
||||
if (this->conf != NULL) {
|
||||
delete this->conf;
|
||||
}
|
||||
|
||||
if (this->udp_server != NULL) {
|
||||
((UDP_Server *)udp_server)->stop ();
|
||||
delete (UDP_Server *)udp_server;
|
||||
}
|
||||
|
||||
if (this->modules != NULL) {
|
||||
delete this->modules;
|
||||
}
|
||||
|
@ -106,7 +113,6 @@ void
|
|||
Pandora_Windows_Service::pandora_init () {
|
||||
string conf_file, interval, debug, transfer_interval;
|
||||
string udp_server_enabled, udp_server_port, udp_server_addr, udp_server_auth_addr;
|
||||
static UDP_Server *udp_server = NULL;
|
||||
|
||||
setPandoraDebug (true);
|
||||
|
||||
|
@ -150,12 +156,12 @@ Pandora_Windows_Service::pandora_init () {
|
|||
|
||||
/* Launch UDP Server */
|
||||
udp_server_enabled = conf->getValue ("udp_server");
|
||||
if (udp_server == NULL && udp_server_enabled.compare ("1") == 0) {
|
||||
if (udp_server_enabled.compare ("1") == 0 && this->udp_server == NULL) {
|
||||
udp_server_port = conf->getValue ("udp_server_port");
|
||||
udp_server_addr = conf->getValue ("udp_server_address");
|
||||
udp_server_auth_addr = conf->getValue ("udp_server_auth_address");
|
||||
udp_server = new UDP_Server (this, udp_server_addr, udp_server_auth_addr, atoi (udp_server_port.c_str ()));
|
||||
udp_server->start ();
|
||||
this->udp_server = new UDP_Server (this, udp_server_addr, udp_server_auth_addr, atoi (udp_server_port.c_str ()));
|
||||
((UDP_Server *)this->udp_server)->start ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ namespace Pandora {
|
|||
long elapsed_transfer_time;
|
||||
long transfer_interval;
|
||||
bool started;
|
||||
|
||||
void *udp_server;
|
||||
|
||||
TiXmlElement *getXmlHeader ();
|
||||
int copyDataFile (string filename);
|
||||
int copyTentacleDataFile (string host,
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||
// vim:tabstop=4:shiftwidth=4:expandtab:
|
||||
|
||||
/*
|
||||
* Copyright (C) 2004-2007 Wu Yongwei <adah at users dot sourceforge dot net>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any
|
||||
* damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute
|
||||
* it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must
|
||||
* not claim that you wrote the original software. If you use this
|
||||
* software in a product, an acknowledgement in the product
|
||||
* documentation would be appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must
|
||||
* not be misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
* This file is part of Stones of Nvwa:
|
||||
* http://sourceforge.net/projects/nvwa
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file static_assert.h
|
||||
*
|
||||
* Template class to check validity duing compile time (adapted from Loki).
|
||||
*
|
||||
* @version 1.2, 2005/11/22
|
||||
* @author Wu Yongwei
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STATIC_ASSERT
|
||||
|
||||
template <bool> struct __nvwa_compile_time_error;
|
||||
template <> struct __nvwa_compile_time_error<true> {};
|
||||
|
||||
#define STATIC_ASSERT(_Expr, _Msg) \
|
||||
{ \
|
||||
__nvwa_compile_time_error<((_Expr) != 0)> ERROR_##_Msg; \
|
||||
(void)ERROR_##_Msg; \
|
||||
}
|
||||
|
||||
#endif // STATIC_ASSERT
|
|
@ -21,7 +21,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <WinSock2.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
#include "udp_server.h"
|
||||
#include "../pandora.h"
|
||||
|
@ -99,6 +99,11 @@ UDP_Server::UDP_Server (Pandora_Windows_Service *service, string address, string
|
|||
this->service = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* UDP_Server destructor.
|
||||
*/
|
||||
UDP_Server::~UDP_Server () {};
|
||||
|
||||
/**
|
||||
* Starts the server.
|
||||
*
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace Pandora {
|
|||
class UDP_Server {
|
||||
public:
|
||||
UDP_Server (Pandora_Windows_Service *service, string address, string auth_address, unsigned int port);
|
||||
~UDP_Server ();
|
||||
virtual ~UDP_Server ();
|
||||
unsigned long getAddress ();
|
||||
unsigned long getAuthAddress ();
|
||||
unsigned long getPort ();
|
||||
|
|
|
@ -206,8 +206,7 @@ Windows_Service::install (LPCTSTR application_binary_path) {
|
|||
service_name, /* name of service */
|
||||
service_display_name, /* service name to display */
|
||||
SERVICE_ALL_ACCESS, /* desired access */
|
||||
SERVICE_WIN32_OWN_PROCESS |
|
||||
SERVICE_INTERACTIVE_PROCESS, /* service type, interactive */
|
||||
SERVICE_WIN32_OWN_PROCESS, /* service type, interactive */
|
||||
SERVICE_AUTO_START, /* start type */
|
||||
SERVICE_ERROR_NORMAL, /* error control type */
|
||||
application_binary_path, /* service's binary */
|
||||
|
|
Loading…
Reference in New Issue