diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8ed064eb1de0ebce012daf328173b420ada0f0a4..684b18f49846cc9c10f1c673d86e419a8a616a0e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -87,10 +87,10 @@ set( CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "" )
 set( CMAKE_SHARED_LIBRARY_LINK_C_FLAGS_DEBUG "-rdynamic" )
 set( CMAKE_SHARED_LIBRARY_LINK_C_FLAGS_RELEASE "" )
 set( CMAKE_EXE_LINKER_FLAGS "" )
-set( CMAKE_EXE_LINKER_FLAGS_DEBUG "-rdynamic" )
+set( CMAKE_EXE_LINKER_FLAGS_DEBUG "-rdynamic -lbfd" )
 set( CMAKE_EXE_LINKER_FLAGS_RELEASE "" )
 set( CMAKE_SHARED_LINKER_FLAGS "" )
-set( CMAKE_SHARED_LINKER_FLAGS_DEBUG "-rdynamic" )
+set( CMAKE_SHARED_LINKER_FLAGS_DEBUG "-rdynamic -lbfd" )
 set( CMAKE_SHARED_LINKER_FLAGS_RELEASE "" )
 
 get_filename_component( CXX_COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME )
diff --git a/src/TNL/Assert.h b/src/TNL/Assert.h
index 6d13e35b11db7e7e304400bb5a3fd772891cbb85..32bb74cbc1b316a3763e4006eb65310795d43d94 100644
--- a/src/TNL/Assert.h
+++ b/src/TNL/Assert.h
@@ -50,7 +50,8 @@
 #include <stdio.h>
 
 #include <TNL/Devices/CudaCallable.h>
-#include <TNL/Debugging/StackBacktrace.h>
+//#include <TNL/Debugging/StackBacktrace.h>
+#include <TNL/Debugging/backtrace2line.h>
 
 namespace TNL {
 namespace Assert {
@@ -90,7 +91,7 @@ printDiagnosticsHost( const char* assertion,
        << "Line: " << line << "\n"
        << "Diagnostics:\n" << diagnostics << std::endl;
 
-   PrintStackBacktrace;
+   PrintStackBacktraceWithLines;
 
    throw AssertionError( str.str() );
 }
@@ -113,7 +114,7 @@ printDiagnosticsHost( const char* assertion,
              << "Line: " << line << "\n"
              << "Diagnostics:\n" << diagnostics << std::endl;
 
-   PrintStackBacktrace;
+   PrintStackBacktraceWithLines;
 }
 #endif // TNL_THROW_ASSERTION_ERROR
 
diff --git a/src/TNL/CMakeLists.txt b/src/TNL/CMakeLists.txt
index cd07ae65910ab69bf004f69bb84231caf78aaab3..7ffd2bf068ae02fedeea46dc54640c793225d596 100644
--- a/src/TNL/CMakeLists.txt
+++ b/src/TNL/CMakeLists.txt
@@ -43,7 +43,8 @@ set( common_SOURCES
      Object.cpp
      Logger.cpp
      String.cpp
-     Timer.cpp )
+     Timer.cpp 
+     Debugging/backtrace2line.cpp)
 
 set( tnl_SOURCES ${tnl_config_SOURCES}
                  ${tnl_containers_SOURCES}
diff --git a/src/TNL/Debugging/backtrace2line.cpp b/src/TNL/Debugging/backtrace2line.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ab2ff8edb83e5ae5b23da4c1eb64286772d65d1c
--- /dev/null
+++ b/src/TNL/Debugging/backtrace2line.cpp
@@ -0,0 +1,271 @@
+#include "backtrace2line.h"
+
+
+namespace TNL {
+namespace Debugging {
+
+
+#ifndef NDEBUG
+
+FileMatch::FileMatch( void* addr ) : mAddress( addr ), mFile( NULL ), mBase( NULL ) {}
+
+int findMatchingFile( struct dl_phdr_info* info, size_t size, void* data )
+{
+   FileMatch* match = (FileMatch*)data;
+ 
+   for ( u32 i = 0; i < info->dlpi_phnum; i++ )
+   {
+      const ElfW(Phdr)& phdr = info->dlpi_phdr[i];
+ 
+      if ( phdr.p_type == PT_LOAD ) 
+      {
+         ElfW(Addr) vaddr = phdr.p_vaddr + info->dlpi_addr;
+         ElfW(Addr) maddr = ElfW(Addr)(match->mAddress);
+         if (( maddr >= vaddr ) && 
+             ( maddr < vaddr + phdr.p_memsz )) 
+         {
+            match->mFile =        info->dlpi_name;
+            match->mBase = (void*)info->dlpi_addr;
+            return 1;
+         }
+      }
+   }
+   return 0;
+}
+
+asymbol** kstSlurpSymtab( bfd* abfd, const char* fileName )
+{
+   if ( !( bfd_get_file_flags( abfd ) & HAS_SYMS ))
+   {
+      printf( "Error bfd file \"%s\" flagged as having no symbols.\n", fileName );
+      return NULL;
+   }
+ 
+   asymbol** syms;
+   unsigned int size;
+ 
+   long symcount = bfd_read_minisymbols( abfd, false, (void**)&syms, &size );
+   if ( symcount == 0 )
+        symcount = bfd_read_minisymbols( abfd, true,  (void**)&syms, &size );
+ 
+   if ( symcount < 0 ) 
+   {
+      printf( "Error bfd file \"%s\", found no symbols.\n", fileName );
+      return NULL;
+   }
+ 
+   return syms;
+}
+
+FileLineDesc::FileLineDesc( asymbol** syms, bfd_vma pc ) : mPc( pc ), mFound( false ), mSyms( syms ) {}
+
+void FileLineDesc::findAddressInSection( bfd* abfd, asection* section )
+{
+   if ( mFound )
+      return;
+ 
+   if (( bfd_get_section_flags( abfd, section ) & SEC_ALLOC ) == 0 )
+      return;
+ 
+   bfd_vma vma = bfd_get_section_vma( abfd, section );
+   if ( mPc < vma )
+      return;
+ 
+   bfd_size_type size = bfd_section_size( abfd, section );
+   if ( mPc >= ( vma + size ))
+      return;
+ 
+   mFound = bfd_find_nearest_line( abfd, section, mSyms, ( mPc - vma ),
+                                   (const char**)&mFilename, (const char**)&mFunctionname, &mLine );
+}
+
+void FindAddressInSection( bfd* abfd, asection* section, void* data )
+{
+   FileLineDesc* desc = (FileLineDesc*)data;
+   //assert( desc );
+   return desc->findAddressInSection( abfd, section );
+}
+
+char** translateAddressesBuf( bfd* abfd, bfd_vma* addr, int numAddr, asymbol** syms )
+{
+   char** ret_buf = NULL;
+   s32    total   = 0;
+ 
+   char   b;
+   char*  buf     = &b;
+   s32    len     = 0;
+ 
+   for ( u32 state = 0; state < 2; state++ ) 
+   {
+      if ( state == 1 ) 
+      {
+         ret_buf = (char**)malloc( total + ( sizeof(char*) * numAddr ));
+         buf = (char*)(ret_buf + numAddr);
+         len = total;
+      }
+ 
+      for ( s32 i = 0; i < numAddr; i++ )
+      {
+         FileLineDesc desc( syms, addr[i] );
+ 
+         if ( state == 1 )
+            ret_buf[i] = buf;
+      
+         bfd_map_over_sections( abfd, FindAddressInSection, (void*)&desc );
+      
+         if ( !desc.mFound ) 
+         {
+            total += snprintf( buf, len, "[0x%llx] \?\? \?\?:0", (long long unsigned int) addr[i] ) + 1;
+ 
+         } else {
+ 
+            const char* name = desc.mFunctionname;
+            if ( name == NULL || *name == '\0' )
+			{
+               name = "??";
+			}
+			else
+			{
+				  //demangle
+			     int status;
+			     size_t funcnamesize = 256;
+			     char* funcname = (char*)malloc(funcnamesize);
+				 char* ret = abi::__cxa_demangle(name, funcname, &funcnamesize, &status);
+				 if (status == 0) {
+					name = ret; // use possibly realloc()-ed string
+				 }
+				 else {
+					// demangling failed. Output function name as a C function with no arguments.
+					//printf("%s-Demangling Faliled\n",name);
+				 }
+			   
+			}
+
+            if ( desc.mFilename != NULL ) 
+            {
+               char* h = strrchr( desc.mFilename, '/' );
+               if ( h != NULL )
+                  desc.mFilename = h + 1;
+            }
+            total += snprintf( buf, len, "%s:%u %s", desc.mFilename ? desc.mFilename : "??", desc.mLine, name ) + 1;
+            // elog << "\"" << buf << "\"\n";
+         }
+      }
+ 
+      if ( state == 1 ) 
+      {
+         buf = buf + total + 1;
+      }
+   }
+ 
+   return ret_buf;
+}
+
+char** processFile( const char* fileName, bfd_vma* addr, int naddr )
+{
+   bfd* abfd = bfd_openr( fileName, NULL );
+   if ( !abfd )
+   {
+      printf( "Error opening bfd file \"%s\"\n", fileName );
+      return NULL;
+   }
+ 
+   if ( bfd_check_format( abfd, bfd_archive ) )
+   {
+      printf( "Cannot get addresses from archive \"%s\"\n", fileName );
+      bfd_close( abfd );
+      return NULL;
+   }
+ 
+   char** matching;
+   if ( !bfd_check_format_matches( abfd, bfd_object, &matching )) 
+   {
+      printf( "Format does not match for archive \"%s\"\n", fileName );
+      bfd_close( abfd );
+      return NULL;
+   }
+ 
+   asymbol** syms = kstSlurpSymtab( abfd, fileName );
+   if ( !syms )
+   {
+      printf( "Failed to read symbol table for archive \"%s\"\n", fileName );
+      bfd_close( abfd );
+      return NULL;
+   }
+ 
+   char** retBuf = translateAddressesBuf( abfd, addr, naddr, syms );
+ 
+   free( syms );
+ 
+   bfd_close( abfd );
+   return retBuf;
+}
+
+char** backtraceSymbols( void* const* addrList, int numAddr )
+{
+   char*** locations = (char***) alloca( sizeof( char** ) * numAddr );
+ 
+   // initialize the bfd library
+   bfd_init(); 
+ 
+   int total = 0;
+   u32 idx = numAddr;
+   for ( s32 i = 0; i < numAddr; i++ )
+   {
+      // find which executable, or library the symbol is from
+      FileMatch match( addrList[--idx] );
+      dl_iterate_phdr( findMatchingFile, &match );
+ 
+      // adjust the address in the global space of your binary to an
+      // offset in the relevant library
+      bfd_vma addr  = (bfd_vma)( addrList[idx] );
+              addr -= (bfd_vma)( match.mBase );
+ 
+      // lookup the symbol
+      if ( match.mFile && strlen( match.mFile ))
+         locations[idx] = processFile( match.mFile,      &addr, 1 );
+      else
+         locations[idx] = processFile( "/proc/self/exe", &addr, 1 );
+ 
+      total += strlen( locations[idx][0] ) + 1;
+   }
+ 
+   // return all the file and line information for each address
+   char** final = (char**)malloc( total + ( numAddr * sizeof( char* )));
+   char* f_strings = (char*)( final + numAddr );
+ 
+   for ( s32 i = 0; i < numAddr; i++ )
+   {
+      strcpy( f_strings, locations[i][0] );
+      free( locations[i] );
+      final[i] = f_strings;
+      f_strings += strlen( f_strings ) + 1;
+   }
+ 
+   return final;
+}
+
+void printStackBacktraceWithLines( FILE *out, unsigned int max_frames)
+{
+
+	void* addrlist[max_frames+1];
+	int addrlen = backtrace(addrlist, sizeof(addrlist) / sizeof(void*));
+	
+	char ** lines=backtraceSymbols( addrlist, addrlen );
+
+	fprintf(out,"\n\nStack Backtrace:\n\n");
+	for(int i=0;i<addrlen;i++)
+	{
+		fprintf(out,"\n==================================================================\n\n");
+		fprintf(out,"%s\n",lines[i]);
+	}
+
+	free(lines);
+
+}
+
+#endif
+
+
+}
+}
diff --git a/src/TNL/Debugging/backtrace2line.h b/src/TNL/Debugging/backtrace2line.h
new file mode 100644
index 0000000000000000000000000000000000000000..7f2bacb283cc52fdcc64c9a61ab8969edb1deb19
--- /dev/null
+++ b/src/TNL/Debugging/backtrace2line.h
@@ -0,0 +1,80 @@
+
+#pragma once
+
+#ifndef NDEBUG
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <execinfo.h>
+#include <bfd.h>
+#include <dlfcn.h>
+#include <link.h>
+#include <linux/types.h>
+#include <execinfo.h>
+#include <cxxabi.h>
+
+
+
+//from: https://oroboro.com/printing-stack-traces-file-line/
+
+
+typedef char 				s8;
+typedef short 				s16;
+typedef int 				s32;
+
+typedef unsigned char 		u8;
+typedef unsigned short 		u16;
+typedef unsigned int 		u32;
+
+#endif
+
+namespace TNL {
+namespace Debugging {
+
+#ifndef NDEBUG
+
+class FileMatch 
+{
+public:
+   FileMatch( void* addr );
+ 
+   void*       mAddress;
+   const char* mFile;
+   void*       mBase;
+};
+
+class FileLineDesc
+{
+public:
+   FileLineDesc( asymbol** syms, bfd_vma pc ); 
+
+   void findAddressInSection( bfd* abfd, asection* section );
+ 
+   bfd_vma      mPc;
+   char*        mFilename;
+   char*        mFunctionname;
+   unsigned int mLine;
+   int          mFound;
+   asymbol**    mSyms;
+};
+
+int findMatchingFile( struct dl_phdr_info* info, size_t size, void* data );
+asymbol** kstSlurpSymtab( bfd* abfd, const char* fileName );
+void FindAddressInSection( bfd* abfd, asection* section, void* data );
+char** translateAddressesBuf( bfd* abfd, bfd_vma* addr, int numAddr, asymbol** syms );
+char** processFile( const char* fileName, bfd_vma* addr, int naddr );
+char** backtraceSymbols( void* const* addrList, int numAddr );
+void printStackBacktraceWithLines( FILE *out = stderr, unsigned int max_frames = 63 );
+
+
+#endif
+
+} // namespace Debugging
+} // namespace TNL
+
+#ifdef NDEBUG
+#define PrintStackBacktraceWithLines
+#else
+#define PrintStackBacktraceWithLines TNL::Debugging::printStackBacktraceWithLines();
+#endif