[med-svn] [Git][med-team/libmaus2][upstream] New upstream version 2.0.719+dfsg

Andreas Tille gitlab at salsa.debian.org
Thu May 28 08:09:04 BST 2020



Andreas Tille pushed to branch upstream at Debian Med / libmaus2


Commits:
a4548fd8 by Andreas Tille at 2020-05-28T08:04:05+02:00
New upstream version 2.0.719+dfsg
- - - - -


16 changed files:

- ChangeLog
- configure.ac
- src/Makefile.am
- src/libmaus2/LibMausConfig.hpp.in
- src/libmaus2/StaticInitialization.cpp
- src/libmaus2/avl/AVLSet.hpp
- src/libmaus2/math/binom.hpp
- src/libmaus2/parallel/SimpleThreadPool.hpp
- src/libmaus2/sorting/InPlaceParallelSort.hpp
- src/libmaus2/sorting/ParallelStableSort.hpp
- + src/libmaus2/util/StackLineTranslator.hpp
- src/libmaus2/util/StackTrace.cpp
- + src/libmaus2/util/StackTraceBufferContainer.cpp
- + src/libmaus2/util/StackTraceBufferContainer.hpp
- src/libmaus2/util/TabEntry.hpp
- src/libmaus2/vcf/VCFParser.hpp


Changes:

=====================================
ChangeLog
=====================================
@@ -1,3 +1,43 @@
+libmaus2 (2.0.719-1) unstable; urgency=medium
+
+  * Make separator in VCFParser::getSampleValueVectorForKey a template argument
+  * Add comments in InPlaceParallelSort
+  * Add comment describing binomRowUpper in Binom class
+
+ -- German Tischler-Höhle <germant at miltenyibiotec.de>  Thu, 14 May 2020 10:36:05 +0200
+
+libmaus2 (2.0.718-1) unstable; urgency=medium
+
+  * Add runFilterFilterFlags in VCFParser
+  * Avoid using operator!= on value_type in AVLSet
+
+ -- German Tischler-Höhle <germant at miltenyibiotec.de>  Thu, 07 May 2020 13:23:27 +0200
+
+libmaus2 (2.0.717-1) unstable; urgency=medium
+
+  * move loop end computation before loop in ParallelStableSort
+
+ -- German Tischler-Höhle <germant at miltenyibiotec.de>  Fri, 17 Apr 2020 20:27:39 +0200
+
+libmaus2 (2.0.716-1) unstable; urgency=medium
+
+  * Add getUnquoted* methods in TabEntry
+
+ -- German Tischler-Höhle <germant at miltenyibiotec.de>  Fri, 17 Apr 2020 14:01:23 +0200
+
+libmaus2 (2.0.715-1) unstable; urgency=medium
+
+  * refactor
+
+ -- German Tischler-Höhle <germant at miltenyibiotec.de>  Thu, 02 Apr 2020 10:09:56 +0200
+
+libmaus2 (2.0.714-1) unstable; urgency=medium
+
+  * Make segfault handler controllable by environment variables LIBMAUS2_TRACE_SEGFAULT/LIBMAUS2_TRACE_SEGFAULT_TRANSLATE
+  * Add StackTraceBufferContainer for obtaining stack traces from segmentation faults
+
+ -- German Tischler-Höhle <germant at miltenyibiotec.de>  Fri, 27 Mar 2020 14:22:47 +0100
+
 libmaus2 (2.0.713-1) unstable; urgency=medium
 
   * Add new interface for setting CRAM compression profile in parallel CRAM encoding


=====================================
configure.ac
=====================================
@@ -1,5 +1,5 @@
-AC_INIT(libmaus2,2.0.713,[germant at miltnyibiotec.de],[libmaus2],[https://github.com/gt1/libmaus2])
-LIBRARY_VERSION=2:713:0
+AC_INIT(libmaus2,2.0.719,[germant at miltnyibiotec.de],[libmaus2],[https://github.com/gt1/libmaus2])
+LIBRARY_VERSION=2:719:0
 AC_MSG_NOTICE([Configuring for source in directory ${srcdir}])
 AC_CANONICAL_SYSTEM
 AC_CANONICAL_HOST
@@ -110,8 +110,16 @@ AC_CHECK_HEADER(features.h, [LIBMAUS2_HAVE_FEATURES_H="#define LIBMAUS2_HAVE_FEA
 AC_CHECK_HEADER(stdint.h, [LIBMAUS2_HAVE_STDINT_H="#define LIBMAUS2_HAVE_STDINT_H"], [LIBMAUS2_HAVE_STDINT_H=])
 AC_CHECK_HEADER(dlfcn.h, [LIBMAUS2_HAVE_DLFCN_H="#define LIBMAUS2_HAVE_DLFCN_H"], [LIBMAUS2_HAVE_DLFCN_H=])
 AC_CHECK_HEADER(sys/prctl.h, [LIBMAUS2_HAVE_SYS_PRCTL_H="#define LIBMAUS2_HAVE_SYS_PRCTL_H"], [LIBMAUS2_HAVE_SYS_PRCTL_H=])
+AC_CHECK_HEADER(libunwind.h, [LIBMAUS2_HAVE_LIBUNWIND_H="#define LIBMAUS2_HAVE_LIBUNWIND_H"], [LIBMAUS2_HAVE_LIBUNWIND_H=])
 AC_LANG_POP
 
+AC_CHECK_LIB([unwind],[unw_backtrace],[unw_backtrace=yes],[unw_backtrace=no])
+
+LIBMAUS2_HAVE_UNW_BACKTRACE=
+if test "${unw_backtrace}" = "yes" ; then
+	LIBMAUS2_HAVE_UNW_BACKTRACE="#define LIBMAUS2_HAVE_UNW_BACKTRACE"
+fi
+
 LIBMAUSCPPFLAGS="${CPPFLAGS}"
 LIBMAUSLDFLAGS="${LDFLAGS}"
 
@@ -410,6 +418,10 @@ fi
 
 LIBMAUSLIBS="${LIBMAUSLIBS} ${ZLIBLIBS}"
 
+if test "${unw_backtrace}" = "yes" ; then
+	LIBMAUSLIBS="${LIBMAUSLIBS} -lunwind"
+fi
+
 AC_LANG_PUSH([C++])
 AC_MSG_CHECKING([whether SIGPIPE exists])
 AC_TRY_COMPILE([#include <csignal>
@@ -3307,4 +3319,6 @@ AC_SUBST([LIBMAUS2_HAVE_IO_LIB_CRAM_ENCODER_GET_FD])
 AC_SUBST([LIBMAUS2_HAVE_IO_LIB_BAMBAM_H])
 AC_SUBST([LIBMAUS2_HAVE_IO_LIB_CRAM_SET_OPTION])
 AC_SUBST([LIBMAUS2_IO_LIB_HAVE_CRAM_OPT_PROFILE])
+AC_SUBST([LIBMAUS2_HAVE_LIBUNWIND_H])
+AC_SUBST([LIBMAUS2_HAVE_UNW_BACKTRACE])
 AC_OUTPUT(Makefile src/Makefile libmaus2.pc libmaus2irods.pc ubuntu.sh src/libmaus2/LibMausConfig.hpp test/Makefile)


=====================================
src/Makefile.am
=====================================
@@ -227,7 +227,8 @@ libmaus2_la_SOURCES = libmaus2/StaticInitialization.cpp \
 	libmaus2/bambam/ChecksumsFactory.cpp \
 	libmaus2/vcf/VCFSortEntry.cpp \
 	libmaus2/parallel/StdMutex.cpp \
-	libmaus2/parallel/StdSpinLock.cpp
+	libmaus2/parallel/StdSpinLock.cpp \
+	libmaus2/util/StackTraceBufferContainer.cpp
 
 noinst_HEADERS = libmaus2/lz/lz4.h
 
@@ -1329,7 +1330,9 @@ libmaus2util_include_HEADERS=\
 	libmaus2/util/AutoArrayUInt8TBaseAllocator.hpp \
 	libmaus2/util/AutoArrayUInt8TBaseTypeInfo.hpp \
 	libmaus2/util/DirectoryStructure.hpp \
-	libmaus2/util/StreamGetObject.hpp
+	libmaus2/util/StreamGetObject.hpp \
+	libmaus2/util/StackTraceBufferContainer.hpp \
+	libmaus2/util/StackLineTranslator.hpp
 
 libmaus2uint_includedir=$(includedir)/libmaus2/uint
 libmaus2uint_include_HEADERS=\


=====================================
src/libmaus2/LibMausConfig.hpp.in
=====================================
@@ -170,3 +170,5 @@
 @LIBMAUS2_HAVE_SYNC_OPS@
 @LIBMAUS2_LARGEFILE_SOURCE@
 @LIBMAUS2_IRODS_NEED_PREFIX@
+ at LIBMAUS2_HAVE_LIBUNWIND_H@
+ at LIBMAUS2_HAVE_UNW_BACKTRACE@


=====================================
src/libmaus2/StaticInitialization.cpp
=====================================
@@ -23,6 +23,59 @@ libmaus2::aio::StreamLock::lock_type libmaus2::aio::StreamLock::coutlock;
 libmaus2::aio::StreamLock::lock_type libmaus2::aio::StreamLock::cerrlock;
 libmaus2::aio::StreamLock::lock_type libmaus2::aio::StreamLock::cinlock;
 
+#include <libmaus2/util/StackTraceBufferContainer.hpp>
+
+libmaus2::util::StackTraceBufferContainer::id_trace_type libmaus2::util::StackTraceBufferContainer::traces[StackTraceBufferContainer_MAXTRACES];
+std::size_t volatile libmaus2::util::StackTraceBufferContainer::numtraces = 0;
+sighandler_t libmaus2::util::StackTraceBufferContainer::prevsig = nullptr;
+jmp_buf libmaus2::util::StackTraceBufferContainer::segenv;
+
+#include <unistd.h>
+
+static int parseVal(char const * p)
+{
+	unsigned int v = 0;
+
+	while ( *p )
+	{
+		if ( *p < '0' || *p > '9' )
+			return -1;
+		else
+		{
+			v *= 10;
+			v += *p-'0';
+			p++;
+		}
+	}
+	return v;
+}
+
+static int initStackTraceBufferContainer()
+{
+	char const * checkseg = getenv("LIBMAUS2_TRACE_SEGFAULT");
+
+	if ( checkseg && parseVal(checkseg) > 0 )
+	{
+		std::cerr << "[V] running libmaus2::util::StackTraceBufferContainer::setup()" << std::endl;
+		return libmaus2::util::StackTraceBufferContainer::setup();
+	}
+	else
+		return 0;
+}
+
+static int initStackTraceBufferContainerTranslate()
+{
+	char const * checkseg = getenv("LIBMAUS2_TRACE_SEGFAULT_TRANSLATE");
+
+	if ( checkseg && parseVal(checkseg) > 0 )
+		return 1;
+	else
+		return 0;
+}
+
+int libmaus2::util::StackTraceBufferContainer::init       = initStackTraceBufferContainer();
+int libmaus2::util::StackTraceBufferContainer::itranslate = initStackTraceBufferContainerTranslate();
+
 #include <libmaus2/types/types.hpp>
 #include <libmaus2/autoarray/AutoArray.hpp>
 #include <libmaus2/util/stringFunctions.hpp>


=====================================
src/libmaus2/avl/AVLSet.hpp
=====================================
@@ -755,7 +755,7 @@ namespace libmaus2
 				const_iterator it(this,prev);
 
 				assert ( it != end() );
-				assert ( *it != v );
+				assert ( order(*it,v) || order(v,*it) );
 
 				if ( order(*it,v) )
 					++it;


=====================================
src/libmaus2/math/binom.hpp
=====================================
@@ -276,9 +276,14 @@ namespace libmaus2
 				return r;
 			}
 
+			/**
+			 * return upper sum of binomial row, i.e.
+			 *
+			 * \sum_{i=k}^{n} binom(i,n) p^{i} (1-p)^{n-i}
+			 **/
 			static double binomRowUpper(double const p, uint64_t const k, uint64_t const n)
 			{
-				if ( p == 1.0 )
+				if ( p >= 1.0 )
 				{
 					if ( k <= n )
 						return 1;


=====================================
src/libmaus2/parallel/SimpleThreadPool.hpp
=====================================
@@ -82,7 +82,7 @@ namespace libmaus2
 			SimpleThreadPool(
 				uint64_t const rnumthreads
 			)
-			: nextpackageid(0), panicflag(false), threads(rnumthreads), AID(rnumthreads)
+			: nextDispatcherId(0), nextpackageid(0), panicflag(false), threads(rnumthreads), AID(rnumthreads)
 			{
 				for ( uint64_t i = 0; i < threads.size(); ++i )
 				{


=====================================
src/libmaus2/sorting/InPlaceParallelSort.hpp
=====================================
@@ -423,7 +423,8 @@ namespace libmaus2
 						p+l0,
 						p+l0+l1,
 						p+l0+l1+r0,
-						numthreads);
+						numthreads
+					);
 
 					// std::cerr << "l1=" << l1 << " r0=" << r0 << std::endl;
 
@@ -620,12 +621,15 @@ namespace libmaus2
 				uint64_t const numthreads
 			)
 			{
+				// size of array
 				uint64_t const n = e-a;
 
 				if ( ! n )
 					return;
 
+				// block size
 				uint64_t const s0 = (n+numthreads-1)/numthreads;
+				// number of blocks
 				uint64_t const b = (n+s0-1)/s0;
 
 				#if defined(_OPENMP)
@@ -638,20 +642,24 @@ namespace libmaus2
 					std::sort(a+low,a+high,order);
 				}
 
-				// std::cerr << "sorted blocks." << std::endl;
-
+				// merge blocks
 				for ( uint64_t s = s0; s < n; s <<= 1 )
 				{
+					// number of input blocks
 					uint64_t const inblocks = (n+s-1)/s;
+					// output blocks
 					uint64_t const outblocks = (inblocks+1)>>1;
 
+					// iterate over output blocks
 					for ( uint64_t o = 0; o < outblocks; ++o )
 					{
+						// input ranges
 						uint64_t const low0 = 2*o*s;
 						uint64_t const high0 = std::min(low0+s,n);
 						uint64_t const low1 = high0;
 						uint64_t const high1 = std::min(low1+s,n);
 
+						// work request vectors
 						std::vector< MergeStepRecSerialRequest<iterator,order_type,base_sort> > reqvec;
 
 						int levelthres = 0;
@@ -659,7 +667,17 @@ namespace libmaus2
 						while ( (1ull<<levelthres) < packsperthread*numthreads )
 							++levelthres;
 
-						mergestepRecLevel(a+low0,high0-low0,high1-low1,order,basesort,0,levelthres,reqvec,numthreads);
+						mergestepRecLevel(
+							a+low0,
+							high0-low0,
+							high1-low1,
+							order,
+							basesort,
+							0,
+							levelthres,
+							reqvec,
+							numthreads
+						);
 
 						// std::cerr << "Calling dispatch for " << reqvec.size() << std::endl;
 


=====================================
src/libmaus2/sorting/ParallelStableSort.hpp
=====================================
@@ -304,11 +304,13 @@ namespace libmaus2
 				 **/
 				void subdispatch()
 				{
+					int64_t const loopend = static_cast<int64_t>(mergeRequests.size());
+
 					#if defined(_OPENMP)
 					unsigned int const num_threads = context.num_threads;
 					#pragma omp parallel for num_threads(num_threads)
 					#endif
-					for ( int64_t t = 0; t < static_cast<int64_t>(mergeRequests.size()); ++t )
+					for ( int64_t t = 0; t < loopend; ++t )
 						mergeRequests[t].dispatch();
 				}
 			};
@@ -344,7 +346,7 @@ namespace libmaus2
 
 				void dispatch()
 				{
-					for ( level_type * cur = levels.size() ? &levels[0] : 0; cur; cur = cur->next )
+					for ( level_type * cur = levels.size() ? &levels[0] : nullptr; cur; cur = cur->next )
 					{
 						cur->dispatch();
 						cur->subdispatch();
@@ -408,11 +410,13 @@ namespace libmaus2
 
 				void dispatch()
 				{
+					int64_t const lnumpacks = static_cast<int64_t>(context->numpacks);
+
 					#if defined(_OPENMP)
 					unsigned int const num_threads = context->num_threads;
 					#pragma omp parallel for num_threads(num_threads)
 					#endif
-					for ( int64_t t = 0; t < static_cast<int64_t>(context->numpacks); ++t )
+					for ( int64_t t = 0; t < lnumpacks; ++t )
 						baseSortRequests[t].dispatch();
 				}
 			};


=====================================
src/libmaus2/util/StackLineTranslator.hpp
=====================================
@@ -0,0 +1,33 @@
+/*
+    libmaus2
+    Copyright (C) 2020 German Tischler-Höhle
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    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, see <http://www.gnu.org/licenses/>..
+*/
+#if ! defined(LIBMAUS2_UTIL_STACKLINETRANSLATOR_HPP)
+#define LIBMAUS2_UTIL_STACKLINETRANSLATOR_HPP
+
+#include <string>
+
+namespace libmaus2
+{
+	namespace util
+	{
+		struct StackLineTranslator
+		{
+			static std::string translate(char const * p, int const deep);
+		};
+	}
+}
+#endif


=====================================
src/libmaus2/util/StackTrace.cpp
=====================================
@@ -18,6 +18,7 @@
 */
 
 #include <libmaus2/util/StackTrace.hpp>
+#include <libmaus2/util/StackLineTranslator.hpp>
 #if defined(__linux__)
 #include <libmaus2/util/PosixExecute.hpp>
 #endif
@@ -56,7 +57,7 @@ static std::string readCommandLine()
 		if ( ! istr_cmdline.is_open() )
 			return std::string();
 
-			std::ostringstream ocmdline;
+		std::ostringstream ocmdline;
 		int c;
 		while ( (c=istr_cmdline.get()) != std::istream::traits_type::eof() )
 			ocmdline.put(c);
@@ -112,6 +113,9 @@ translate
                         std::pair < std::string, std::string > B = components(A.first,'(',')');
 
                         #if defined(LIBMAUS2_DEBUG_COMPILED)
+                        #if 1
+                        ostr << libmaus2::util::StackLineTranslator::translate(trace[i].c_str(),1 /* deep */) << std::endl;
+                        #else
                         std::string const execname = findIfSelf(B.first);
                         std::string const & addr = A.second;
 
@@ -148,6 +152,7 @@ translate
 
                         //ostr << B.first << "(" << B.second << ")" << "[" << A.second << ":" << addrout << "]\n";
                         ostr << execname << "(" << B.second << ")" << "[" << A.second << ":" << addrout << "]\n";
+                        #endif
                         #else
                         if ( B.second.find_last_of('+') != std::string::npos )
                         {


=====================================
src/libmaus2/util/StackTraceBufferContainer.cpp
=====================================
@@ -0,0 +1,531 @@
+/*
+    libmaus2
+    Copyright (C) 2009-2013 German Tischler
+    Copyright (C) 2011-2013 Genome Research Limited
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    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, see <http://www.gnu.org/licenses/>..
+*/
+#if defined(LIBMAUS2_HAVE_LIBUNWIND_H)
+#include <libunwind.h>
+#endif
+
+#if defined(LIBMAUS2_HAVE_EXECINFO_H)
+#include <execinfo.h>
+#endif
+
+#include <setjmp.h>
+
+#include <libmaus2/util/StackTraceBufferContainer.hpp>
+#include <libmaus2/util/StackLineTranslator.hpp>
+#include <libmaus2/aio/StreamLock.hpp>
+
+void libmaus2::util::StackTraceBufferContainer::reset()
+{
+	numtraces = 0;
+	signal(SIGSEGV,prevsig);
+}
+
+int libmaus2::util::StackTraceBufferContainer::setup()
+{
+	numtraces = 0;
+
+	prevsig = signal(SIGSEGV,sigseghandler);
+
+	if ( setjmp(segenv) )
+	{
+		// signal(SIGSEGV,prevsig);
+
+		{
+			std::cerr << "[E] libmaus2::util::StackTraceBufferContainer: setjmp returned non zero (segfault)" << std::endl;
+
+			std::thread::id const id = ::std::this_thread::get_id();
+
+			std::size_t const loopend = std::min(
+				static_cast<std::size_t>(StackTraceBufferContainer_MAXTRACES),
+				static_cast<std::size_t>(numtraces)
+			);
+
+			for ( ::std::size_t i = 0; i < loopend; ++i )
+				if ( traces[i].first == id )
+				{
+					StackTraceBuffer & buf = traces[i].second;
+
+					if ( buf.stacktracebufn > 0 )
+					{
+						#if defined(LIBMAUS2_HAVE_EXECINFO_H) && defined(LIBMAUS2_HAVE_BACKTRACE)
+						char ** syms = backtrace_symbols(&buf.stacktracebuf[0],buf.stacktracebufn);
+
+						for ( int i = 0; i < buf.stacktracebufn; ++i )
+						{
+							std::string const s = StackLineTranslator::translate(syms[i],itranslate);
+							std::cerr << "[" << i << "]=" << s << "\n";
+						}
+
+						free(syms);
+						#endif
+					}
+
+				}
+		}
+
+		abort();
+	}
+
+	return 0;
+}
+
+#if defined(LIBMAUS2_HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#include <cstring>
+
+void libmaus2::util::StackTraceBufferContainer::sigseghandler(int)
+{
+	uint64_t const traceid = __sync_fetch_and_add(&numtraces,1);
+
+	// if ( traceid < StackTraceBufferContainer_MAXTRACES )
+	if ( !traceid )
+	{
+		std::thread::id const id = ::std::this_thread::get_id();
+		traces[traceid].first = id;
+
+		#if defined(LIBMAUS2_HAVE_EXECINFO_H) && defined(LIBMAUS2_HAVE_BACKTRACE)
+		StackTraceBuffer & lbuf = traces[traceid].second;
+		lbuf.stacktracebufn = backtrace(&(lbuf.stacktracebuf[0]),StackTraceBufferContainer_STACKTRACEBUFSIZE);
+		#endif
+
+		longjmp(segenv,1);
+	}
+	else
+	{
+		while ( true )
+		{
+			::sleep(1);
+		}
+	}
+}
+
+template<typename type>
+struct Array
+{
+	type * p;
+
+	void allocate(::std::size_t const n)
+	{
+		try
+		{
+			p = new type[n];
+		}
+		catch(...)
+		{
+			p = nullptr;
+		}
+	}
+
+	Array()
+	: p(nullptr)
+	{
+
+	}
+
+	Array(::std::size_t const n)
+	: p(nullptr)
+	{
+		allocate(n);
+	}
+
+	~Array()
+	{
+		if ( p )
+			delete [] p;
+	}
+};
+
+#include <sstream>
+
+#if defined(LIBMAUS2_HAVE_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+#if defined(LIBMAUS2_HAVE_SYS_WAIT_H)
+#include <sys/wait.h>
+#endif
+
+#if defined(LIBMAUS2_HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#if defined(LIBMAUS2_HAVE_FCNTL_H)
+#include <fcntl.h>
+#endif
+
+#include <vector>
+
+#include <cstdlib>
+#include <cstring>
+#include <libmaus2/util/Demangle.hpp>
+
+static int callCommand(std::vector<std::string> const & V, std::string const & outtmp, std::string & r)
+{
+	int rmk = -1;
+	int ex = EXIT_SUCCESS;
+	char * cp = nullptr;
+	pid_t pid = -1;
+	size_t todo = 0;
+	char * pp = nullptr;
+	off_t fs = 0;
+	off_t fs0 = 0;
+	size_t s = 0;
+
+	for ( uint64_t i = 0; i < V.size(); ++i )
+		s += V[i].size()+1;
+
+	Array<char> Atemp(outtmp.size()+1);
+	Array<char> Ctemp(s);
+	Array<char *> Ptemp(V.size()+1);
+	Array<char> T;
+
+	if ( ! Atemp.p )
+	{
+		ex = EXIT_FAILURE;
+		goto cleanup;
+	}
+	::std::fill(Atemp.p,Atemp.p+outtmp.size()+1,0);
+	::std::copy(outtmp.begin(),outtmp.end(),Atemp.p);
+
+
+	if ( ! Ctemp.p )
+	{
+		ex = EXIT_FAILURE;
+		goto cleanup;
+	}
+	if ( ! Ptemp.p )
+	{
+		ex = EXIT_FAILURE;
+		goto cleanup;
+	}
+	cp = Ctemp.p;
+	for ( uint64_t i = 0; i < V.size(); ++i )
+	{
+		Ptemp.p[i] = cp;
+		std::size_t const l = V[i].size();
+		std::copy(V[i].begin(),V[i].end(),cp);
+		cp += l;
+		*(cp++) = 0;
+	}
+	Ptemp.p[V.size()] = nullptr;
+
+	rmk = mkstemp(Atemp.p);
+
+	if ( rmk < 0 )
+	{
+		ex = EXIT_FAILURE;
+		goto cleanup;
+	}
+
+	pid = fork();
+
+	if ( pid == static_cast<pid_t>(-1) )
+	{
+		ex = EXIT_FAILURE;
+		goto cleanup;
+	}
+	else if ( pid == 0 )
+	{
+		int const nullfd = ::open("/dev/null",O_WRONLY);
+
+		if ( nullfd < 0 )
+			_exit(EXIT_FAILURE);
+
+		::close(STDOUT_FILENO);
+		::close(STDERR_FILENO);
+
+		int const rdup = ::dup2(rmk,STDOUT_FILENO);
+
+		if ( rdup < 0 )
+			_exit(EXIT_FAILURE);
+
+		int const rdup2 = ::dup2(nullfd,STDERR_FILENO);
+		if ( rdup2 < 0 )
+			_exit(EXIT_FAILURE);
+
+		execv(Ptemp.p[0],Ptemp.p);
+
+		_exit(EXIT_FAILURE);
+	}
+
+	int status;
+	while ( true )
+	{
+		pid_t const rpid = waitpid(pid,&status,0);
+
+		if ( rpid == pid )
+			break;
+		else if ( rpid == static_cast<pid_t>(-1) )
+		{
+			int const error = errno;
+
+			switch ( error )
+			{
+				case EINTR:
+				case EAGAIN:
+					break;
+				default:
+				{
+					ex = EXIT_FAILURE;
+					goto cleanup;
+				}
+			}
+		}
+	}
+
+	if ( status != 0 )
+	{
+		ex = EXIT_FAILURE;
+		goto cleanup;
+	}
+
+	fs = lseek(rmk,0,SEEK_END);
+
+	if ( fs == static_cast<off_t>(-1) )
+	{
+		ex = EXIT_FAILURE;
+		goto cleanup;
+	}
+
+	fs0 = lseek(rmk,0,SEEK_SET);
+
+	if ( fs0 == static_cast<off_t>(-1) )
+	{
+		ex = EXIT_FAILURE;
+		goto cleanup;
+	}
+
+	T.allocate(fs);
+	if ( ! T.p )
+	{
+		ex = EXIT_FAILURE;
+		goto cleanup;
+	}
+	pp = T.p;
+	todo = fs;
+
+	while ( todo )
+	{
+		::ssize_t const r = ::read(rmk,pp,todo);
+
+		if ( r < 0 )
+		{
+			int const error = errno;
+			switch ( error )
+			{
+				case EINTR:
+				case EAGAIN:
+					break;
+				default:
+				{
+					ex = EXIT_FAILURE;
+					goto cleanup;
+				}
+			}
+		}
+		else if ( r == 0 )
+		{
+			ex = EXIT_FAILURE;
+			goto cleanup;
+		}
+		else
+		{
+			pp += r;
+			todo -= r;
+		}
+	}
+
+	r = std::string(T.p,T.p+fs);
+
+	cleanup:
+	if ( rmk >= 0 )
+	{
+		::close(rmk);
+		::remove(Atemp.p);
+		rmk = -1;
+	}
+
+	return ex;
+}
+
+std::string libmaus2::util::StackLineTranslator::translate(char const * ip, int const deep)
+{
+	// /home/baer/src/git/libmaus2/src/.libs/libmaus2.so.2(_ZN8libmaus24util25StackTraceBufferContainer13sigseghandlerEi+0x70) [0x7f328cc1e980]
+	if ( ! ip )
+		return std::string();
+
+	char const * path_a = ip;
+	char const * path_e = path_a;
+
+	while ( *path_e && *path_e != '(' )
+		++path_e;
+
+	if ( !*path_e )
+		return std::string(ip);
+
+	char const * symoffstart = path_e+1;
+	char const * symoffend = symoffstart;
+
+	while ( *symoffend && *symoffend != ')' )
+		++symoffend;
+
+	if ( !*symoffend )
+		return std::string(ip);
+
+	char const * symstart = symoffstart;
+	char const * symend = symstart;
+
+	while ( symend != symoffend && *symend != '+' )
+		++symend;
+
+	if ( symend == symoffend )
+		return std::string(ip);
+
+	char const * offstart = symend+1;
+	char const * offend = symoffend;
+
+	std::string const path(path_a,path_e);
+	std::string const symoff(symoffstart,symoffend);
+	std::string const sym(symstart,symend);
+	std::string const off(offstart,offend);
+
+	std::string p = path + "(" + libmaus2::util::Demangle::demangleName(sym) + "+" + off + ")";
+
+	if ( ! deep )
+		return p;
+
+	std::string const tmpprefix = "/tmp/libmaus2_";
+	std::ostringstream nmtmpostr;
+	#if defined(LIBMAUS2_HAVE_GETPID)
+	nmtmpostr << tmpprefix << getpid() << "_XXXXXX";
+	#else
+	nmtmpostr << tmpprefix << "_XXXXXX";
+	#endif
+	std::string const nmtmp = nmtmpostr.str();
+
+	std::vector<std::string> Vcom;
+	Vcom.push_back("/usr/bin/nm");
+	Vcom.push_back(path);
+
+	std::string rnm;
+	int const r_nm = callCommand(Vcom,nmtmp,rnm);
+
+	if ( r_nm != EXIT_SUCCESS )
+		return p;
+
+	// std::cerr << "path=" << path << " symoff=" << symoff << " sym=" << sym << " off=" << off << " nmtmp=" << nmtmp << std::endl;
+
+	uint64_t uaddr = 0;
+	bool haveaddr = false;
+
+	std::istringstream nm_istr(rnm);
+	std::string line;
+	while ( std::getline(nm_istr,line) )
+	{
+		uint64_t low = 0;
+		std::vector<std::string> V;
+		while ( low < line.size() )
+		{
+			while ( low < line.size() && isspace(line[low]) )
+				++low;
+
+			if ( low < line.size() )
+			{
+				uint64_t high = low+1;
+				while ( high < line.size() && !isspace(line[high]) )
+					++high;
+
+				V.push_back(line.substr(low,high-low));
+
+				low = high;
+			}
+		}
+		if ( 2 < V.size() && V[2] == sym )
+		{
+			std::string const saddr = V[0];
+
+			char const * pa = saddr.c_str();
+			char const * pe = pa + saddr.size();
+
+			while ( pa != pe && *pa == '0' )
+				++pa;
+
+			std::string const laddr(pa,pe);
+
+			if ( laddr.size() )
+			{
+				// std::string const paddr = std::string("0x")+laddr;
+				std::istringstream istr(laddr);
+				uint64_t luaddr;
+				istr >> std::hex >> luaddr;
+
+				if ( istr && istr.peek() == std::istream::traits_type::eof() )
+				{
+					uaddr = luaddr;
+					haveaddr = true;
+				}
+			}
+		}
+	}
+
+	if ( sym.size() && ! haveaddr )
+		return p;
+
+
+	if ( off.size() < 2 || off.substr(0,2) != "0x" )
+		return p;
+
+	std::istringstream offistr(off.substr(2));
+	uint64_t uoff;
+	offistr >> std::hex >> uoff;
+	if ( !offistr && offistr.peek() != std::istream::traits_type::eof() )
+		return p;
+
+	std::ostringstream addrostr;
+	addrostr << "0x" << std::hex << (uaddr+uoff);
+	std::string const addr = addrostr.str();
+
+	std::vector<std::string> Vaddr;
+	Vaddr.push_back("/usr/bin/addr2line");
+	Vaddr.push_back("-f");
+	Vaddr.push_back("-e");
+	Vaddr.push_back(path);
+	Vaddr.push_back(addr);
+
+	std::string raddrline;
+	int const r_addrline = callCommand(Vaddr,nmtmp,raddrline);
+
+	if ( r_addrline != EXIT_SUCCESS )
+		return p;
+
+	std::vector<std::string> Vad;
+	std::istringstream adistr(raddrline);
+	while ( std::getline(adistr,line) )
+		Vad.push_back(line);
+
+	if ( Vad.size() < 2 )
+		return p;
+
+	std::ostringstream outostr;
+	outostr << path << "(" << libmaus2::util::Demangle::demangleName(Vad[0]) << "+" << off << ")" << "[" << Vad[1] << "]";
+
+	return outostr.str();
+}


=====================================
src/libmaus2/util/StackTraceBufferContainer.hpp
=====================================
@@ -0,0 +1,65 @@
+/*
+    libmaus2
+    Copyright (C) 2020 German Tischler-Höhle
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    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, see <http://www.gnu.org/licenses/>..
+*/
+#if ! defined(LIBMAUS2_UTIL_STACKTRACEBUFFERCONTAINER_HPP)
+#define LIBMAUS2_UTIL_STACKTRACEBUFFERCONTAINER_HPP
+
+#include <libmaus2/LibMausConfig.hpp>
+
+#include <csignal>
+#include <iostream>
+#include <thread>
+#include <utility>
+#include <atomic>
+#include <setjmp.h>
+
+namespace libmaus2
+{
+	namespace util
+	{
+		struct StackTraceBufferContainer
+		{
+			#define StackTraceBufferContainer_STACKTRACEBUFSIZE 30
+			#define StackTraceBufferContainer_MAXTRACES 32
+
+			typedef void * stacktracebuf_t[StackTraceBufferContainer_STACKTRACEBUFSIZE];
+
+			struct StackTraceBuffer
+			{
+				stacktracebuf_t stacktracebuf;
+				int stacktracebufn;
+
+				StackTraceBuffer() : stacktracebufn(0) {}
+			};
+
+			typedef std::pair<std::thread::id,StackTraceBuffer> id_trace_type;
+
+			static id_trace_type traces[StackTraceBufferContainer_MAXTRACES];
+			static std::size_t volatile numtraces;
+
+			static jmp_buf segenv;
+			static sighandler_t prevsig;
+			static int init;
+			static int itranslate;
+
+			static int setup();
+			static void reset();
+			static void sigseghandler(int);
+		};
+	}
+}
+#endif


=====================================
src/libmaus2/util/TabEntry.hpp
=====================================
@@ -124,12 +124,37 @@ namespace libmaus2
 				return std::pair<char const *,char const *>(a+LP.first,a+LP.second);
 			}
 
+			std::pair<char const *,char const *> getUnquoted(uint64_t const i, char const * a) const
+			{
+				P LP = (*this)[i];
+
+				if (
+					(LP.second - LP.first >= 2)
+					&&
+					a[LP.first] == quote_sym
+					&&
+					a[LP.second-1] == quote_sym
+				)
+				{
+					LP.first += 1;
+					LP.second -= 1;
+				}
+
+				return std::pair<char const *,char const *>(a+LP.first,a+LP.second);
+			}
+
 			std::string getString(uint64_t const i, char const * a) const
 			{
 				std::pair<char const *,char const *> const P = get(i,a);
 				return std::string(P.first,P.second);
 			}
 
+			std::string getUnquotedString(uint64_t const i, char const * a) const
+			{
+				std::pair<char const *,char const *> const P = getUnquoted(i,a);
+				return std::string(P.first,P.second);
+			}
+
 			std::vector<std::string> getStrings(char const * a) const
 			{
 				std::vector<std::string> V(size());
@@ -138,6 +163,14 @@ namespace libmaus2
 				return V;
 			}
 
+			std::vector<std::string> getUnquotedStrings(char const * a) const
+			{
+				std::vector<std::string> V(size());
+				for ( uint64_t i = 0; i < size(); ++i )
+					V[i] = getUnquotedString(i,a);
+				return V;
+			}
+
 			template<typename value_type>
 			value_type getParsed(uint64_t const i, char const * a) const
 			{


=====================================
src/libmaus2/vcf/VCFParser.hpp
=====================================
@@ -1009,6 +1009,49 @@ namespace libmaus2
 				return out;
 			}
 
+			static std::ostream & runFilterFilterFlags(std::istream & in, std::ostream & out, std::vector<std::string> const & Vfilter)
+			{
+				libmaus2::trie::Trie<char> TR;
+				TR.insertContainer(Vfilter);
+				::libmaus2::trie::LinearHashTrie<char,uint32_t>::unique_ptr_type LHT(TR.toLinearHashTrie<uint32_t>());
+
+				VCFParser VCF(in);
+				VCF.printText(out);
+
+				std::pair<bool, char const *> E;
+				libmaus2::util::TabEntry<> T;
+				libmaus2::util::TabEntry<';'> TI;
+
+				while ( (E=VCF.readEntry(T)).first )
+				{
+					if ( 6 < T.size() )
+					{
+						std::pair<char const *,char const *> IP = T.get(6,E.second);
+						TI.parse(IP.first,IP.first,IP.second);
+
+						bool ok = false;
+						for ( uint64_t i = 0; i < TI.size(); ++i )
+						{
+							std::pair<char const *,char const *> P = TI.get(i,IP.first);
+
+							int64_t const id = LHT->searchCompleteNoFailure(P.first,P.second);
+							if ( id >= 0 )
+								ok = true;
+						}
+
+						if ( ok )
+						{
+							char const * a = E.second;
+							char const * e = T.get(T.size()-1,a).second;
+							out.write(a,e-a);
+							out.put('\n');
+						}
+					}
+				}
+
+				return out;
+			}
+
 
 			static std::ostream & runFilterInfo(std::istream & in, std::ostream & out, std::string const & filter)
 			{
@@ -1022,6 +1065,18 @@ namespace libmaus2
 				return runFilterInfo(in,out,Vfilter);
 			}
 
+			static std::ostream & runFilterFilterFlags(std::istream & in, std::ostream & out, std::string const & filter)
+			{
+				libmaus2::util::TabEntry<';'> TE;
+				TE.parse(filter.c_str(),filter.c_str(),filter.c_str()+filter.size());
+
+				std::vector<std::string> Vfilter;
+				for ( uint64_t i = 0; i < TE.size(); ++i )
+					Vfilter.push_back(TE.getString(i,filter.c_str()));
+
+				return runFilterFilterFlags(in,out,Vfilter);
+			}
+
 			static std::ostream & runFilterSamples(std::istream & in, std::ostream & out, std::vector<std::string> const & Vfilter)
 			{
 				libmaus2::trie::Trie<char> TR;
@@ -1199,7 +1254,9 @@ namespace libmaus2
 				uint64_t const samplenum,
 				libmaus2::autoarray::AutoArray<
 					std::pair<
+						// key
 						std::pair<char const *,char const *>,
+						// value
 						std::pair<char const *,char const *>
 					> > & A
 			)
@@ -1287,6 +1344,7 @@ namespace libmaus2
 				return std::string(P.first,P.second);
 			}
 
+			template<char separator>
 			static uint64_t getSampleValueVectorForKey(
 				std::string const & key,
 				libmaus2::util::TabEntry<> const & T,
@@ -1299,7 +1357,7 @@ namespace libmaus2
 						std::pair<char const *,char const *>,
 						std::pair<char const *,char const *>
 					> > & A,
-				libmaus2::util::TabEntry<','> & TC,
+				libmaus2::util::TabEntry<separator> & TC,
 				libmaus2::autoarray::AutoArray< std::pair<char const *,char const *> > & O
 			)
 			{
@@ -1318,7 +1376,7 @@ namespace libmaus2
 				return TC.size();
 			}
 
-			template<typename type>
+			template<typename type, char separator = ','>
 			static uint64_t getSampleValueVectorForKeyParsed(
 				std::string const & key,
 				libmaus2::util::TabEntry<> const & T,
@@ -1331,7 +1389,7 @@ namespace libmaus2
 						std::pair<char const *,char const *>,
 						std::pair<char const *,char const *>
 					> > & A,
-				libmaus2::util::TabEntry<','> & TC,
+				libmaus2::util::TabEntry<separator> & TC,
 				libmaus2::autoarray::AutoArray< type > & O
 			)
 			{
@@ -1364,7 +1422,7 @@ namespace libmaus2
 				return TC.size();
 			}
 
-			template<typename type>
+			template<typename type, char separator = ','>
 			static std::vector<type> getSampleValueVectorForKeyParsed(
 				std::string const & key,
 				libmaus2::util::TabEntry<> const & T,
@@ -1379,7 +1437,7 @@ namespace libmaus2
 						std::pair<char const *,char const *>,
 						std::pair<char const *,char const *>
 					> > A;
-				libmaus2::util::TabEntry<','> TC;
+				libmaus2::util::TabEntry<separator> TC;
 				libmaus2::autoarray::AutoArray< type > O;
 
 				uint64_t const o = getSampleValueVectorForKeyParsed(key,T,a,TSC0,TSC1,samplenum,A,TC,O);



View it on GitLab: https://salsa.debian.org/med-team/libmaus2/-/commit/a4548fd8b67afb339172f8636bd76f33c895491f

-- 
View it on GitLab: https://salsa.debian.org/med-team/libmaus2/-/commit/a4548fd8b67afb339172f8636bd76f33c895491f
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20200528/70abfdd7/attachment-0001.html>


More information about the debian-med-commit mailing list