Skip to content

A few minor downport issues #180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 24 additions & 29 deletions ddprof-lib/gtest/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,42 +37,37 @@ tasks.withType(StripSymbols).configureEach { task ->
}
}

def buildResourcesTask = tasks.register("buildResources", Exec) {
def buildNativeLibsTask = tasks.register("buildNativeLibs") {
group = 'build'
description = "Build the resources for the Google Tests"
description = "Build the native libs for the Google Tests"

onlyIf {
hasGtest && !project.hasProperty('skip-native') && !project.hasProperty('skip-gtest') && os().isLinux()
}

def targetDir = project(':ddprof-lib').file('build/test/resources/unresolved-functions')

commandLine "sh", "-c", "cd ${project(':ddprof-lib').projectDir}/src/test/resources/unresolved-functions && make TARGET_DIR=${targetDir}"

inputs.files project(':ddprof-lib').files('src/test/resources/unresolved-functions')
outputs.file "${targetDir}/main"
}

def buildSmallLibTask = tasks.register("buildSmallLib", Exec) {
group = 'build'
description = "Build the small-lib shared library for the Google Tests"

onlyIf {
hasGtest && !project.hasProperty('skip-native') && !project.hasProperty('skip-gtest') && os().isLinux()
def srcDir = project(':ddprof-lib').file('src/test/resources/native-libs')
def targetDir = project(':ddprof-lib').file('build/test/resources/native-libs/')

// Move the exec calls to the execution phase
doLast {
srcDir.eachDir { dir ->
def libName = dir.name
def libDir = file("${targetDir}/${libName}")
def libSrcDir = file("${srcDir}/${libName}")

exec {
commandLine "sh", "-c", """
echo "Processing library: ${libName} @ ${libSrcDir}"
mkdir -p ${libDir}
cd ${libSrcDir}
make TARGET_DIR=${libDir}
"""
}
}
}

def sourceDir = project(':ddprof-lib').file('src/test/resources/small-lib')
def targetDir = project(':ddprof-lib').file('build/test/resources/small-lib')

commandLine "sh", "-c", """
mkdir -p ${targetDir}
cd ${sourceDir} && g++ -fPIC -shared -o ${targetDir}/libsmall-lib.so *.cpp
"""

inputs.files fileTree(sourceDir) {
include '**/*.cpp'
}
outputs.file "${targetDir}/libsmall-lib.so"
inputs.files project(':ddprof-lib').files('src/test/resources/native-libs/**/*')
outputs.dir "${targetDir}"
}

def gtestAll = tasks.register("gtest") {
Expand Down Expand Up @@ -204,7 +199,7 @@ tasks.whenTaskAdded { task ->
gtestTask.get().dependsOn gtestExecuteTask.get()
if (os().isLinux()) {
// custom binaries for tests are built only on linux
gtestExecuteTask.get().dependsOn(buildResourcesTask, buildSmallLibTask)
gtestExecuteTask.get().dependsOn(buildNativeLibs)
}
gtestAll.get().dependsOn gtestExecuteTask.get()
}
Expand Down
22 changes: 9 additions & 13 deletions ddprof-lib/src/main/cpp/arch.h
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
/*
* Copyright 2017 Andrei Pangin
*
* 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.
* Copyright The async-profiler authors
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef _ARCH_H
#define _ARCH_H

#include <stddef.h>

#ifndef unlikely
# define unlikely(x) (__builtin_expect(!!(x), 0))
#endif

#define callerPC() __builtin_return_address(0)

#ifdef _LP64
# define LP64_ONLY(code) code
#else // !_LP64
# define LP64_ONLY(code)
#endif // _LP64


typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
Expand Down
15 changes: 2 additions & 13 deletions ddprof-lib/src/main/cpp/callTraceStorage.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
/*
* Copyright 2020 Andrei Pangin
*
* 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.
* Copyright The async-profiler authors
* SPDX-License-Identifier: Apache-2.0
*/

#include "callTraceStorage.h"
Expand Down
99 changes: 64 additions & 35 deletions ddprof-lib/src/main/cpp/codeCache.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
/*
* Copyright 2016 Andrei Pangin
*
* 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.
* Copyright The async-profiler authors
* SPDX-License-Identifier: Apache-2.0
*/

#include "codeCache.h"
Expand Down Expand Up @@ -274,48 +263,88 @@ void CodeCache::findSymbolsByPrefix(std::vector<const char *> &prefixes,
}
}

void CodeCache::addImport(void **entry, const char *name) {
switch (name[0]) {
case 'd':
if (strcmp(name, "dlopen") == 0) {
_imports[im_dlopen] = entry;
void CodeCache::saveImport(ImportId id, void** entry) {
for (int ty = 0; ty < NUM_IMPORT_TYPES; ty++) {
if (_imports[id][ty] == nullptr) {
_imports[id][ty] = entry;
return;
}
}
break;
case 'p':
if (strcmp(name, "pthread_create") == 0) {
_imports[im_pthread_create] = entry;
} else if (strcmp(name, "pthread_exit") == 0) {
_imports[im_pthread_exit] = entry;
} else if (strcmp(name, "pthread_setspecific") == 0) {
_imports[im_pthread_setspecific] = entry;
}

void CodeCache::addImport(void **entry, const char *name) {
switch (name[0]) {
case 'c':
if (strcmp(name, "calloc") == 0) {
saveImport(im_calloc, entry);
}
break;
case 'd':
if (strcmp(name, "dlopen") == 0) {
saveImport(im_dlopen, entry);
}
break;
case 'f':
if (strcmp(name, "free") == 0) {
saveImport(im_free, entry);
}
break;
case 'm':
if (strcmp(name, "malloc") == 0) {
saveImport(im_malloc, entry);
}
break;
case 'p':
if (strcmp(name, "pthread_create") == 0) {
saveImport(im_pthread_create, entry);
} else if (strcmp(name, "pthread_exit") == 0) {
saveImport(im_pthread_exit, entry);
} else if (strcmp(name, "pthread_setspecific") == 0) {
saveImport(im_pthread_setspecific, entry);
} else if (strcmp(name, "poll") == 0) {
saveImport(im_poll, entry);
}
break;
case 'r':
if (strcmp(name, "realloc") == 0) {
saveImport(im_realloc, entry);
}
break;
}
break;
}
}

void **CodeCache::findImport(ImportId id) {
if (!_imports_patchable) {
makeImportsPatchable();
_imports_patchable = true;
}
return _imports[id];
return _imports[id][PRIMARY];
}

void CodeCache::patchImport(ImportId id, void *hook_func) {
void **entry = findImport(id);
if (!_imports_patchable) {
makeImportsPatchable();
_imports_patchable = true;
}

for (int ty = 0; ty < NUM_IMPORT_TYPES; ty++) {void **entry = _imports[id][ty];
if (entry != NULL) {
*entry = hook_func;
}
}}
}

void CodeCache::makeImportsPatchable() {
void **min_import = (void **)-1;
void **max_import = NULL;
for (int i = 0; i < NUM_IMPORTS; i++) {
if (_imports[i] != NULL && _imports[i] < min_import)
min_import = _imports[i];
if (_imports[i] != NULL && _imports[i] > max_import)
max_import = _imports[i];
for (int j = 0; j < NUM_IMPORT_TYPES; j++) {
void** entry = _imports[i][j];
if (entry == NULL) continue;
if (entry < min_import)
min_import = entry;
if (entry > max_import)
max_import = entry;
}
}

if (max_import != NULL) {
Expand Down
31 changes: 16 additions & 15 deletions ddprof-lib/src/main/cpp/codeCache.h
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
/*
* Copyright 2017 Andrei Pangin
*
* 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.
* Copyright The async-profiler authors
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef _CODECACHE_H
Expand All @@ -35,9 +24,20 @@ enum ImportId {
im_pthread_create,
im_pthread_exit,
im_pthread_setspecific,
im_poll,
im_malloc,
im_calloc,
im_realloc,
im_free,
NUM_IMPORTS
};

enum ImportType {
PRIMARY,
SECONDARY,
NUM_IMPORT_TYPES
};

class NativeFunc {
private:
short _lib_index;
Expand All @@ -58,7 +58,7 @@ class NativeFunc {
if (posix_memalign((void**)(&func), sizeof(NativeFunc*), sizeof(NativeFunc)) != 0) {
return -1;
}
return func->_lib_index;
return func->_lib_index;
}

static bool isMarked(const char *name) { return from(name)->_mark != 0; }
Expand Down Expand Up @@ -100,7 +100,7 @@ class CodeCache {
unsigned int _plt_offset;
unsigned int _plt_size;

void **_imports[NUM_IMPORTS];
void **_imports[NUM_IMPORTS][NUM_IMPORT_TYPES];
bool _imports_patchable;
bool _debug_symbols;

Expand All @@ -113,6 +113,7 @@ class CodeCache {

void expand();
void makeImportsPatchable();
void saveImport(ImportId id, void** entry);

public:
explicit CodeCache(const char *name, short lib_index = -1,
Expand Down
23 changes: 6 additions & 17 deletions ddprof-lib/src/main/cpp/flightRecorder.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
/*
* Copyright 2018 Andrei Pangin
* Copyright 2021, 2023 Datadog, Inc
*
* 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.
* Copyright The async-profiler authors
* SPDX-License-Identifier: Apache-2.0
* Copyright 2021, 2025 Datadog, Inc
*/

#include <assert.h>
Expand Down Expand Up @@ -133,7 +122,7 @@ void Lookup::fillJavaMethodInfo(MethodInfo *mi, jmethodID method,
jvmtiEnv *jvmti = VM::jvmti();

jvmtiPhase phase;
jclass method_class;
jclass method_class = NULL;
// invariant: these strings must remain null, or be assigned by JVMTI
char *class_name = nullptr;
char *method_name = nullptr;
Expand Down Expand Up @@ -590,10 +579,10 @@ bool Recording::parseAgentProperties() {
if (get_agent_props != NULL && to_string != NULL) {
jobject props = env->CallStaticObjectMethod(vm_support, get_agent_props);
jniExceptionCheck(env);
if (props != NULL) {
if (props != NULL && !env->ExceptionCheck()) {
jstring str = (jstring)env->CallObjectMethod(props, to_string);
jniExceptionCheck(env);
if (str != NULL) {
if (str != NULL && !env->ExceptionCheck()) {
_agent_properties = (char *)env->GetStringUTFChars(str, NULL);
}
}
Expand Down
17 changes: 3 additions & 14 deletions ddprof-lib/src/main/cpp/profiler.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
/*
* Copyright 2016 Andrei Pangin
* Copyright 2024 Datadog, Inc
*
* 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.
* Copyright The async-profiler authors
* SPDX-License-Identifier: Apache-2.0
* Copyright 2024, 2025 Datadog, Inc
*/

#include "profiler.h"
Expand Down
Loading
Loading