1ae9ce8ad2
This protects against memory corruptions, and a cascade of issues, such as the following: Attaching to process 56245 [New LWP 56246] [New LWP 56252] [New LWP 56253] [New LWP 56254] [New LWP 56362] [New LWP 56364] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". 0x00007fda228f7d2d in __GI___pthread_timedjoin_ex (threadid=140574279595776, thread_return=0x0, abstime=0x0, block=<optimized out>) at pthread_join_common.c:89 89 pthread_join_common.c: No such file or directory. Thread 7 (Thread 0x7fda197fa700 (LWP 56364)): #0 __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135 #1 0x00007fda228f9023 in __GI___pthread_mutex_lock (mutex=0x55e9937567e0 <SigHandlerTrap>) at ../nptl/pthread_mutex_lock.c:78 #2 0x000055e9934cd4fe in __gthread_mutex_lock (__mutex=0x55e9937567e0 <SigHandlerTrap>) at /usr/include/x86_64-linux-gnu/c++/7/bits/gthr-default.h:748 #3 std::mutex::lock (this=0x55e9937567e0 <SigHandlerTrap>) at /usr/include/c++/7/bits/std_mutex.h:103 #4 std::unique_lock<std::mutex>::lock (this=<synthetic pointer>) at /usr/include/c++/7/bits/std_mutex.h:267 #5 std::unique_lock<std::mutex>::unique_lock (__m=..., this=<synthetic pointer>) at /usr/include/c++/7/bits/std_mutex.h:197 #6 SigUtil::handleFatalSignal (signal=11) at common/SigUtil.cpp:214 #7 <signal handler called> #8 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_capacity (this=<optimized out>, __capacity=0) at /usr/include/c++/7/bits/basic_string.h:200 #9 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (__str=..., this=<optimized out>) at /usr/include/c++/7/bits/basic_string.h:542 #10 std::_Construct<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > ( __p=<optimized out>) at /usr/include/c++/7/bits/stl_construct.h:75 #11 std::__uninitialized_copy<false>::__uninit_copy<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> (__result=0x7fd9f40017b0, __last=..., __first=...) at /usr/include/c++/7/bits/stl_uninitialized.h:83 #12 std::uninitialized_copy<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> (__result=<optimized out>, __last=..., __first=...) at /usr/include/c++/7/bits/stl_uninitialized.h:134 #13 std::__uninitialized_copy_a<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (__result=<optimized out>, __last=..., __first=...) at /usr/include/c++/7/bits/stl_uninitialized.h:289 #14 std::__uninitialized_move_if_noexcept_a<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > (__alloc=..., __result=<optimized out>, __last=0x55e995662850, __first=<optimized out>) at /usr/include/c++/7/bits/stl_uninitialized.h:312 #15 std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_realloc_insert<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> ( this=this@entry=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>, __position=<error: Cannot access memory at address 0x3735003238323a>, __args#0="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp") at /usr/include/c++/7/bits/vector.tcc:424 #16 0x000055e9934aa829 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::push_back (__x="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp", this=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>) at /usr/include/c++/7/bits/stl_vector.h:948 #17 (anonymous namespace)::FileDeleter::registerForDeletion (file="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp", this=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>) at common/FileUtil.cpp:69 #18 FileUtil::getTempFilePath (srcDir=..., srcFilename=..., dstFilenamePrefix=...) at common/FileUtil.cpp:97 #19 0x00007fda216b51c9 in helpers::getDocumentPathAndURL (docFilename="viewcursor.odp", documentPath="", documentURL="", prefix="loadTorture_viewcursor.odp_") at ./helpers.hpp:151 #20 0x00007fda216ad007 in UnitLoadTorture::loadTorture (this=<optimized out>, testname="loadTorture_viewcursor.odp ", docName="viewcursor.odp", thread_count=thread_count@entry=3, max_jitter_ms=<optimized out>, max_jitter_ms@entry=75) at UnitLoadTorture.cpp:41 #21 0x00007fda216ad7dd in UnitLoadTorture::<lambda()>::operator() (__closure=0x55e994dbc758) at UnitLoadTorture.cpp:186 #22 std::__invoke_impl<void, UnitLoadTorture::testLoadTorture()::<lambda()> > (__f=...) at /usr/include/c++/7/bits/invoke.h:60 #23 std::__invoke<UnitLoadTorture::testLoadTorture()::<lambda()> > (__fn=...) at /usr/include/c++/7/bits/invoke.h:95 #24 std:🧵:_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::_M_invoke<0> (this=0x55e994dbc758) at /usr/include/c++/7/thread:234 #25 std:🧵:_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::operator() (this=0x55e994dbc758) at /usr/include/c++/7/thread:243 #26 std:🧵:_State_impl<std:🧵:_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > > >::_M_run(void) (this=0x55e994dbc750) at /usr/include/c++/7/thread:186 #27 0x00007fda22de366f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #28 0x00007fda228f66db in start_thread (arg=0x7fda197fa700) at pthread_create.c:463 #29 0x00007fda2261f88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 Thread 6 (Thread 0x7fd9fffff700 (LWP 56362)): #0 __lll_lock_wait_private () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95 #1 0x00007fda225952db in __GI___libc_malloc (bytes=bytes@entry=3635) at malloc.c:3063 #2 0x00007fda2262f364 in __backtrace_symbols (array=array@entry=0x7fd9ffffc540, size=size@entry=26) at backtracesyms.c:69 #3 0x000055e9934cc439 in SigUtil::dumpBacktrace () at common/SigUtil.cpp:253 #4 0x000055e9934cd5ae in SigUtil::handleFatalSignal (signal=6) at common/SigUtil.cpp:236 #5 <signal handler called> #6 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 #7 0x00007fda2253e801 in __GI_abort () at abort.c:79 #8 0x00007fda22587897 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fda226b4b9a "%s ") at ../sysdeps/posix/libc_fatal.c:181 #9 0x00007fda2258e90a in malloc_printerr (str=str@entry=0x7fda226b2e0e "malloc(): memory corruption") at malloc.c:5350 #10 0x00007fda22592994 in _int_malloc (av=av@entry=0x7fda00000020, bytes=bytes@entry=32) at malloc.c:3738 #11 0x00007fda225952ed in __GI___libc_malloc (bytes=32) at malloc.c:3065 #12 0x00007fda22db9258 in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #13 0x00007fda244adaae in __gnu_cxx::new_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::allocate (this=0x7fd9ffffe740, __n=1) at /usr/include/c++/5/ext/new_allocator.h:104 #14 0x00007fda244ad300 in __gnu_cxx::__alloc_traits<std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::allocate (__a=..., __n=1) at /usr/include/c++/5/ext/alloc_traits.h:182 #15 0x00007fda244ac858 in std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_allocate (this=0x7fd9ffffe740, __n=1) at /usr/include/c++/5/bits/stl_vector.h:170 #16 0x00007fda244ab7c7 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_insert_aux (this=0x7fd9ffffe740, __position=non-dereferenceable iterator for std::vector, __x="home") at /usr/include/c++/5/bits/vector.tcc:353 #17 0x00007fda244aada2 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::push_back (this=0x7fd9ffffe740, __x="home") at /usr/include/c++/5/bits/stl_vector.h:925 #18 0x00007fda2350ddcb in Poco::Path::pushDirectory (this=0x7fd9ffffe6c0, dir="home") at src/Path.cpp:471 #19 0x00007fda2350ea27 in Poco::Path::parseUnix (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:671 #20 0x00007fda2350cd6b in Poco::Path::assign (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:182 #21 0x00007fda2350c1be in Poco::Path::Path (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:54 #22 0x00007fda2350d33a in Poco::Path::makeAbsolute (this=0x7fd9ffffe8f0) at src/Path.cpp:318 #23 0x00007fda216b52ca in helpers::getDocumentPathAndURL (docFilename="setclientpart.ods", documentPath="/tmp/loadTorture_setclientpart.ods_ae70d2e_setclientpart.ods", documentURL="", prefix="loadTorture_setclientpart.ods_") at ./helpers.hpp:153 #24 0x00007fda216ad007 in UnitLoadTorture::loadTorture (this=<optimized out>, testname="loadTorture_setclientpart.ods ", docName="setclientpart.ods", thread_count=thread_count@entry=3, max_jitter_ms=<optimized out>, max_jitter_ms@entry=75) at UnitLoadTorture.cpp:41 #25 0x00007fda216ad7dd in UnitLoadTorture::<lambda()>::operator() (__closure=0x55e994cffe18) at UnitLoadTorture.cpp:186 #26 std::__invoke_impl<void, UnitLoadTorture::testLoadTorture()::<lambda()> > (__f=...) at /usr/include/c++/7/bits/invoke.h:60 #27 std::__invoke<UnitLoadTorture::testLoadTorture()::<lambda()> > (__fn=...) at /usr/include/c++/7/bits/invoke.h:95 #28 std:🧵:_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::_M_invoke<0> (this=0x55e994cffe18) at /usr/include/c++/7/thread:234 #29 std:🧵:_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::operator() (this=0x55e994cffe18) at /usr/include/c++/7/thread:243 #30 std:🧵:_State_impl<std:🧵:_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > > >::_M_run(void) (this=0x55e994cffe10) at /usr/include/c++/7/thread:186 #31 0x00007fda22de366f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #32 0x00007fda228f66db in start_thread (arg=0x7fd9fffff700) at pthread_create.c:463 #33 0x00007fda2261f88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95 Change-Id: Ib60954e49e692082e686cb3fdc5fc9d5cfbc83c9 Reviewed-on: https://gerrit.libreoffice.org/83047 Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Tested-by: Michael Meeks <michael.meeks@collabora.com>
90 lines
4 KiB
C++
90 lines
4 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#ifndef INCLUDED_FILEUTIL_HPP
|
|
#define INCLUDED_FILEUTIL_HPP
|
|
|
|
#include <string>
|
|
|
|
#include <Poco/File.h>
|
|
#include <Poco/Path.h>
|
|
|
|
namespace FileUtil
|
|
{
|
|
/// Create a secure, random directory path.
|
|
std::string createRandomDir(const std::string& path);
|
|
|
|
// Save data to a file (overwriting an existing file if necessary) with checks for errors. Write
|
|
// to a temporary file in the same directory that is then atomically renamed to the desired name
|
|
// if everything goes well. In case of any error, both the destination file (if it already
|
|
// exists) and the temporary file (if was created, or existed already) are removed. Return true
|
|
// if everything succeeded.
|
|
bool saveDataToFileSafely(const std::string& fileName, const char* data, size_t size);
|
|
|
|
// We work around some of the mess of using the same sources both on the server side and in unit
|
|
// tests with conditional compilation based on BUILDING_TESTS.
|
|
|
|
#ifndef BUILDING_TESTS
|
|
// Send a 'error:' message with the specified cmd and kind parameters to all connected
|
|
// clients. This function can be called either in loolwsd or loolkit processes, even if only
|
|
// loolwsd obviously has contact with the actual clients; in loolkit it will be forwarded to
|
|
// loolwsd for redistribution. (This function must be implemented separately in each program
|
|
// that uses it, it is not in Util.cpp.)
|
|
void alertAllUsers(const std::string& cmd, const std::string& kind);
|
|
#else
|
|
// No-op implementation in the test programs
|
|
inline void alertAllUsers(const std::string&, const std::string&)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
// Add the file system that 'path' is located on to a list of file systems that are periodically
|
|
// checked for available space. The list is initially empty.
|
|
void registerFileSystemForDiskSpaceChecks(const std::string& path);
|
|
|
|
// Perform the check. If the free space on any of the registered file systems is below 5%, call
|
|
// 'alertAllUsers("internal", "diskfull")'. The check will be made no more often than once a
|
|
// minute if cacheLastCheck is set to true.
|
|
std::string checkDiskSpaceOnRegisteredFileSystems(const bool cacheLastCheck = true);
|
|
|
|
// Check disk space on a specific file system, the one where 'path' is located. This does not
|
|
// add that file system to the list used by 'registerFileSystemForDiskSpaceChecks'. If the free
|
|
// space on the file system is below 5%, return false, otherwise true. Note that this function
|
|
// does not call 'alertAllUsers'.
|
|
bool checkDiskSpace(const std::string& path);
|
|
|
|
/// Safely remove a file or directory.
|
|
/// Supresses exception when the file is already removed.
|
|
/// This can happen when there is a race (unavoidable) or when
|
|
/// we don't care to check before we remove (when no race exists).
|
|
void removeFile(const std::string& path, const bool recursive = false);
|
|
|
|
inline void removeFile(const Poco::Path& path, const bool recursive = false)
|
|
{
|
|
removeFile(path.toString(), recursive);
|
|
}
|
|
|
|
/// Make a temp copy of a file, and prepend it with a prefix.
|
|
std::string getTempFilePath(const std::string& srcDir, const std::string& srcFilename,
|
|
const std::string& dstFilenamePrefix);
|
|
|
|
/// Make a temp copy of a file.
|
|
/// Primarily used by tests to avoid tainting the originals.
|
|
/// srcDir shouldn't end with '/' and srcFilename shouldn't contain '/'.
|
|
/// Returns the created file path.
|
|
inline std::string getTempFilePath(const std::string& srcDir, const std::string& srcFilename)
|
|
{
|
|
return getTempFilePath(srcDir, srcFilename, std::string());
|
|
}
|
|
|
|
} // end namespace FileUtil
|
|
|
|
#endif
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|