Rollback #7374
Valgrind is complaining about use of uninitialized memory in absl::GetStackTrace, and the cases where it complains the backtraces are incomplete. Note: this means that jemalloc heap profiling no longer works out of the box. Advanced users who want to enable jemalloc heap profiling will now have to revert this change and build from source.
This commit is contained in:
parent
b361bd8e7a
commit
fbf5830bb2
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "fmt/format.h"
|
||||
#include "fdbserver/workloads/workloads.actor.h"
|
||||
#include "flow/SignalSafeUnwind.h"
|
||||
#include "flow/actorcompiler.h" // This must be the last #include.
|
||||
|
||||
// Stress test the slow task profiler or flow profiler
|
||||
|
@ -42,22 +43,24 @@ struct SlowTaskWorkload : TestWorkload {
|
|||
|
||||
ACTOR static Future<Void> go() {
|
||||
wait(delay(1));
|
||||
int64_t phc = dl_iterate_phdr_calls;
|
||||
int64_t startProfilesDeferred = getNumProfilesDeferred();
|
||||
int64_t startProfilesOverflowed = getNumProfilesOverflowed();
|
||||
int64_t startProfilesCaptured = getNumProfilesCaptured();
|
||||
int64_t exc = 0;
|
||||
fprintf(stdout, "Slow task starting\n");
|
||||
fprintf(stderr, "Slow task starting\n");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
fprintf(stdout, " %d\n", i);
|
||||
fprintf(stderr, " %d\n", i);
|
||||
double end = timer() + 1;
|
||||
while (timer() < end) {
|
||||
do_slow_exception_thing(&exc);
|
||||
}
|
||||
}
|
||||
fmt::print(stdout,
|
||||
"Slow task complete: {0} exceptions; {1} profiles deferred, {2} profiles overflowed, {3} profiles "
|
||||
"captured\n",
|
||||
fmt::print(stderr,
|
||||
"Slow task complete: {0} exceptions; {1} calls to dl_iterate_phdr, {2}"
|
||||
" profiles deferred, {3} profiles overflowed, {4} profiles captured\n",
|
||||
exc,
|
||||
dl_iterate_phdr_calls - phc,
|
||||
getNumProfilesDeferred() - startProfilesDeferred,
|
||||
getNumProfilesOverflowed() - startProfilesOverflowed,
|
||||
getNumProfilesCaptured() - startProfilesCaptured);
|
||||
|
|
|
@ -90,6 +90,10 @@ void initProfiling() {
|
|||
net2backtraces = new volatile void*[net2backtraces_max];
|
||||
other_backtraces = new volatile void*[net2backtraces_max];
|
||||
|
||||
// According to folk wisdom, calling this once before setting up the signal handler makes
|
||||
// it async signal safe in practice :-/
|
||||
backtrace(const_cast<void**>(other_backtraces), net2backtraces_max);
|
||||
|
||||
sigemptyset(&sigprof_set);
|
||||
sigaddset(&sigprof_set, SIGPROF);
|
||||
}
|
||||
|
|
|
@ -3765,7 +3765,7 @@ void profileHandler(int sig) {
|
|||
ps->timestamp = checkThreadTime.is_lock_free() ? checkThreadTime.load() : 0;
|
||||
|
||||
// SOMEDAY: should we limit the maximum number of frames from backtrace beyond just available space?
|
||||
size_t size = platform::raw_backtrace(ps->frames, net2backtraces_max - net2backtraces_offset - 2);
|
||||
size_t size = backtrace(ps->frames, net2backtraces_max - net2backtraces_offset - 2);
|
||||
|
||||
ps->length = size;
|
||||
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* SignalSafeUnwind.cpp
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2022 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "flow/SignalSafeUnwind.h"
|
||||
|
||||
int64_t dl_iterate_phdr_calls = 0;
|
||||
|
||||
#if defined(__linux__) && !defined(USE_SANITIZER)
|
||||
|
||||
#include <link.h>
|
||||
#include <mutex>
|
||||
|
||||
static int (*chain_dl_iterate_phdr)(int (*callback)(struct dl_phdr_info* info, size_t size, void* data),
|
||||
void* data) = nullptr;
|
||||
|
||||
static void initChain() {
|
||||
static std::once_flag flag;
|
||||
|
||||
// Ensure that chain_dl_iterate_phdr points to the "real" function that we are overriding
|
||||
std::call_once(flag, []() { *(void**)&chain_dl_iterate_phdr = dlsym(RTLD_NEXT, "dl_iterate_phdr"); });
|
||||
|
||||
if (!chain_dl_iterate_phdr) {
|
||||
criticalError(FDB_EXIT_ERROR, "SignalSafeUnwindError", "Unable to find dl_iterate_phdr symbol");
|
||||
}
|
||||
}
|
||||
|
||||
// This overrides the function in libc!
|
||||
extern "C" int dl_iterate_phdr(int (*callback)(struct dl_phdr_info* info, size_t size, void* data), void* data) {
|
||||
interlockedIncrement64(&dl_iterate_phdr_calls);
|
||||
|
||||
initChain();
|
||||
|
||||
setProfilingEnabled(0);
|
||||
int result = chain_dl_iterate_phdr(callback, data);
|
||||
setProfilingEnabled(1);
|
||||
return result;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* SignalSafeUnwind.h
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2022 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLOW_SIGNAL_SAFE_UNWIND
|
||||
#define FLOW_SIGNAL_SAFE_UNWIND
|
||||
#pragma once
|
||||
|
||||
#include "flow/Platform.h"
|
||||
|
||||
// This can be used by tests to measure the number of calls to dl_iterate_phdr intercepted
|
||||
extern int64_t dl_iterate_phdr_calls;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue