-
Notifications
You must be signed in to change notification settings - Fork 427
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix virtual to binary addr conversion for processes that have an unco…
…mmon virtual memory mapping (#1637) Summary: Fix virtual to binary addr conversion for processes that have an uncommon virtual memory mapping Our previous virtual to binary address conversion logic assumed that the first offset within `/proc/$PID/maps` was the correct offset to apply for PIE binaries. There are certain cases, such as when an unlimited stack ulimit is applied, where this assumption doesn't hold true (see the linked issue before for more details). This change adjusts our conversion logic to take into account the correct `/proc/$PID/maps` entry so address conversion works in all known cases. Relevant Issues: #1630 Type of change: /kind bug Test Plan: Verified the following: - [x] New test verifies the status quo case as well as the situation reported in #1630 - [x] Verified `perf_profiler_bpf_test` passes when the perf profiler uses the ELF symbolizer --------- Signed-off-by: Dom Del Nano <[email protected]>
- Loading branch information
Showing
7 changed files
with
260 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright 2018- The Pixie 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. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "src/stirling/obj_tools/address_converter.h" | ||
|
||
#include "src/stirling/obj_tools/testdata/containers/vaddr_convert_self_func_container.h" | ||
#include "src/stirling/testing/common.h" | ||
|
||
namespace px { | ||
namespace stirling { | ||
namespace obj_tools { | ||
|
||
TEST(ElfAddressConverterTest, VirtualAddrToBinaryAddr) { | ||
VaddrConvertSelfFuncContainer container; | ||
ASSERT_OK(container.Run()); | ||
|
||
int status = -1; | ||
testing::Timeout t(std::chrono::minutes{1}); | ||
while (status == -1 && !t.TimedOut()) { | ||
status = container.GetStatus(); | ||
std::this_thread::sleep_for(std::chrono::milliseconds{200}); | ||
} | ||
EXPECT_EQ(0, status); | ||
} | ||
|
||
TEST(ElfAddressConverterTest, VirtualAddrToBinaryAddrForReorderedVirtualMemoryMappings) { | ||
// Setting an unlimited stack size ulimit causes the VMAs of a process to be reordered and | ||
// caused a previous crash (as described in https://github.com/pixie-io/pixie/issues/1630). | ||
VaddrConvertSelfFuncContainer container; | ||
ASSERT_OK(container.Run(std::chrono::seconds{5}, {"--ulimit=stack=-1"})); | ||
|
||
int status = -1; | ||
testing::Timeout t(std::chrono::minutes{1}); | ||
while (status == -1 && !t.TimedOut()) { | ||
status = container.GetStatus(); | ||
std::this_thread::sleep_for(std::chrono::milliseconds{200}); | ||
} | ||
EXPECT_EQ(0, status); | ||
} | ||
|
||
} // namespace obj_tools | ||
} // namespace stirling | ||
} // namespace px |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# | ||
# 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. | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
load("@io_bazel_rules_docker//cc:image.bzl", "cc_image") | ||
load("//bazel:pl_build_system.bzl", "pl_cc_binary", "pl_cc_test_library") | ||
|
||
package(default_visibility = ["//src/stirling/obj_tools:__subpackages__"]) | ||
|
||
pl_cc_binary( | ||
name = "vaddr_convert_self_func", | ||
srcs = ["vaddr_convert_self_func.cc"], | ||
deps = [ | ||
"//src/stirling/obj_tools:cc_library", | ||
], | ||
) | ||
|
||
cc_image( | ||
name = "vaddr_convert_self_func_image", | ||
base = "//:pl_cc_base_debug_image", | ||
binary = ":vaddr_convert_self_func", | ||
) | ||
|
||
pl_cc_test_library( | ||
name = "vaddr_convert_self_func_container", | ||
srcs = glob( | ||
["*.cc"], | ||
exclude = [ | ||
"vaddr_convert_self_func.cc", | ||
], | ||
), | ||
hdrs = glob( | ||
[ | ||
"*.h", | ||
], | ||
), | ||
data = [ | ||
":vaddr_convert_self_func_image.tar", | ||
], | ||
deps = ["//src/common/testing/test_utils:cc_library"], | ||
) |
62 changes: 62 additions & 0 deletions
62
src/stirling/obj_tools/testdata/containers/vaddr_convert_self_func.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Copyright 2018- The Pixie 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. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "src/stirling/obj_tools/address_converter.h" | ||
#include "src/stirling/utils/proc_path_tools.h" | ||
|
||
// Using extern C to avoid name mangling since ElfReader must be able to address this | ||
// by its symbol name. | ||
extern "C" { | ||
void TestFunc() {} | ||
|
||
} // extern "C" | ||
|
||
using px::stirling::GetSelfPath; | ||
using px::stirling::obj_tools::ElfAddressConverter; | ||
using px::stirling::obj_tools::ElfReader; | ||
using px::stirling::obj_tools::SymbolMatchType; | ||
|
||
// This utility performs an assertion that the ElfAddressConverter::VirtualAddrToBinaryAddr function | ||
// returns the correct (consistent with ElfReader and `nm` cli output) binary address for a given | ||
// function. This is used to test our address conversion logic when a PIE binary is memory mapped | ||
// differently from the common scenario (where the process's ELF segments are mapped at the | ||
// lowest VMA), such as when an unlimited stack size ulimit is set on a process. | ||
int main() { | ||
LOG(INFO) << "Running"; | ||
|
||
// This sleep is required otherwise when it is run inside a container (via ContainerRunner) we | ||
// will fail to detect the child process's pid during the test case that uses this. | ||
sleep(5); | ||
|
||
std::filesystem::path self_path = GetSelfPath().ValueOrDie(); | ||
PX_ASSIGN_OR(auto elf_reader, ElfReader::Create(self_path.string()), return -1); | ||
PX_ASSIGN_OR(std::vector<ElfReader::SymbolInfo> syms, | ||
elf_reader->ListFuncSymbols("TestFunc", SymbolMatchType::kSubstr)); | ||
|
||
PX_ASSIGN_OR(auto converter, ElfAddressConverter::Create(elf_reader.get(), getpid()), return -1); | ||
auto symbol_addr = converter->VirtualAddrToBinaryAddr(reinterpret_cast<uint64_t>(&TestFunc)); | ||
|
||
auto expected_addr = syms[0].address; | ||
if (symbol_addr != expected_addr) { | ||
LOG(ERROR) << absl::Substitute( | ||
"Expected ElfAddressConverter address=$0 to match binary address=$1", symbol_addr, | ||
expected_addr); | ||
return -1; | ||
} | ||
return 0; | ||
} |
38 changes: 38 additions & 0 deletions
38
src/stirling/obj_tools/testdata/containers/vaddr_convert_self_func_container.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* Copyright 2018- The Pixie 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. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "src/common/base/base.h" | ||
#include "src/common/testing/test_environment.h" | ||
#include "src/common/testing/test_utils/container_runner.h" | ||
|
||
using px::ContainerRunner; | ||
|
||
class VaddrConvertSelfFuncContainer : public ContainerRunner { | ||
public: | ||
VaddrConvertSelfFuncContainer() | ||
: ContainerRunner(px::testing::BazelRunfilePath(kBazelImageTar), kInstanceNamePrefix, | ||
kReadyMessage) {} | ||
|
||
private: | ||
static constexpr std::string_view kBazelImageTar = | ||
"src/stirling/obj_tools/testdata/containers/vaddr_convert_self_func_image.tar"; | ||
static constexpr std::string_view kInstanceNamePrefix = "vaddr_convert_self_func_container"; | ||
static constexpr std::string_view kReadyMessage = "Running"; | ||
}; |