Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
70b1a33
build with debug symbol by default
taegyunkim Aug 12, 2025
bd0b38a
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 12, 2025
d01f289
strip debug symbols
taegyunkim Aug 12, 2025
a2ebbe9
strip symbols when not debug
taegyunkim Aug 12, 2025
48d7d41
use -g
taegyunkim Aug 12, 2025
9353a9e
ignore .debug files
taegyunkim Aug 12, 2025
00ace36
ignore *.debug files
taegyunkim Aug 12, 2025
ddcaefb
strip debug symbols to .debug for libdd_wrapper
taegyunkim Aug 12, 2025
aa38f9d
update
taegyunkim Aug 13, 2025
48c49bd
use hash
taegyunkim Aug 13, 2025
46ce257
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 13, 2025
2fc6965
--archs
taegyunkim Aug 13, 2025
f366bb5
Revert "update"
taegyunkim Aug 13, 2025
b5abe41
Revert "--archs"
taegyunkim Aug 13, 2025
c64d46f
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 13, 2025
530091f
handle this later
taegyunkim Aug 14, 2025
edeb6ed
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 14, 2025
f4f199f
include debug symbols to be installed/packaged
taegyunkim Aug 14, 2025
d291bbd
extract debug symbols into separate zip files
taegyunkim Aug 14, 2025
58da60c
set --output-dir
taegyunkim Aug 14, 2025
18a7573
set versions for packages used
taegyunkim Aug 14, 2025
f3ef896
this is redundant
taegyunkim Aug 14, 2025
b95b0b5
compile C extensions and Cython extensions with debug symbols when Re…
taegyunkim Aug 14, 2025
19e9cfa
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 14, 2025
d39714a
remove newline
taegyunkim Aug 14, 2025
77ce358
specify audithweel versions
taegyunkim Aug 14, 2025
81ef283
update
taegyunkim Aug 14, 2025
0489f5b
extract debug symbols before auditwheel
taegyunkim Aug 15, 2025
e937f93
revert
taegyunkim Aug 15, 2025
1ce1254
use auditwheel command
taegyunkim Aug 15, 2025
8e6800d
dont generate debug file here
taegyunkim Aug 15, 2025
093cc10
generate debug files before auditwheel and delocate-wheel to make sur…
taegyunkim Aug 15, 2025
ca9dee1
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 15, 2025
ffec034
fix docs build
taegyunkim Aug 15, 2025
7bb1874
Merge branch 'taegyunkim/prof-12156-with-debug' of github.com:DataDog…
taegyunkim Aug 15, 2025
c4a068a
fix script for older python versions
taegyunkim Aug 15, 2025
a304967
keep the same directory structure
taegyunkim Aug 15, 2025
43baefc
make sure to not strip these symbols
taegyunkim Aug 15, 2025
0b66d1c
format
taegyunkim Aug 15, 2025
8dbb8fa
copy over debugwheelhouse
taegyunkim Aug 15, 2025
39665b3
Format code
taegyunkim Aug 15, 2025
5cf1291
remove newlines
taegyunkim Aug 15, 2025
0ed4e99
no need to include these, as theyre generated while auditing and delo…
taegyunkim Aug 15, 2025
637524f
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 15, 2025
ba11f4f
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 18, 2025
2690477
update dirs
taegyunkim Aug 18, 2025
db44478
create directory under {dest_dir}
taegyunkim Aug 18, 2025
99641b2
fix for mac
taegyunkim Aug 18, 2025
c18f125
linux: put to /output container output dir, mac: dont move it to dest…
taegyunkim Aug 18, 2025
e10abf0
add comments
taegyunkim Aug 18, 2025
5b2ee80
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 18, 2025
bf6f03c
only download wheels and source-dist
taegyunkim Aug 18, 2025
e6c6ac0
enable memalloc assertions only on Debug compile mode
taegyunkim Aug 19, 2025
9bff627
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 19, 2025
e9c35d0
verify step
taegyunkim Aug 19, 2025
543284e
fix lto options for appleclang
taegyunkim Aug 19, 2025
8da48c9
fix lto
taegyunkim Aug 19, 2025
bd9a3e7
recursive copy for mac
taegyunkim Aug 19, 2025
823b3fb
use in instead of startswith
taegyunkim Aug 19, 2025
0bae713
format
taegyunkim Aug 19, 2025
9c0bcff
use taegyunkim/dd-compile-release for serverless benchmarks
taegyunkim Aug 20, 2025
70ca0fc
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 20, 2025
357ad7e
strip debug symbol when release
taegyunkim Aug 20, 2025
8f0d7b9
add debug print for compile mode
taegyunkim Aug 20, 2025
d7eaa71
fix typo
taegyunkim Aug 20, 2025
5bb7ab4
update comment
taegyunkim Aug 20, 2025
e9d7fc2
Revive try_strip_symbols for minsizerel
taegyunkim Aug 20, 2025
32ada00
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 20, 2025
33495a0
Merge branch 'taegyunkim/prof-12156-with-debug' of github.com:DataDog…
taegyunkim Aug 20, 2025
ae5d0fc
remove debug print
taegyunkim Aug 20, 2025
e2d4f3c
update comments
taegyunkim Aug 20, 2025
3c22db9
supply ignore pattern having libddwaf* by default
taegyunkim Aug 20, 2025
3356d8d
macOS: error when no debug symbols
taegyunkim Aug 20, 2025
3de37a2
Fail if no debug symbols
taegyunkim Aug 20, 2025
20d7a62
Revert to use head DataDog/serverless-tools
taegyunkim Aug 20, 2025
58cb4bf
fix typo
taegyunkim Aug 20, 2025
b74d4c2
update comments and dont strip rust binary from here
taegyunkim Aug 21, 2025
fe34d65
no need to set -g in linker options
taegyunkim Aug 21, 2025
e5dc580
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 21, 2025
f10708e
minimize diff
taegyunkim Aug 21, 2025
4b8a645
minimize diff
taegyunkim Aug 21, 2025
91321e5
update comment
taegyunkim Aug 21, 2025
3dddf37
remove unnecessary changes
taegyunkim Aug 21, 2025
2c79734
minimize diff and add comment
taegyunkim Aug 21, 2025
d1a2865
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 21, 2025
c1949ff
format
taegyunkim Aug 21, 2025
81c4a02
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Aug 26, 2025
919326b
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Sep 1, 2025
8fbb5a5
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Sep 2, 2025
20bc06d
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Sep 2, 2025
6c9535e
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Sep 3, 2025
d8f6e51
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Sep 4, 2025
8d651c7
update docs on how to set substitute-path
taegyunkim Sep 4, 2025
8337a61
update with expected output
taegyunkim Sep 4, 2025
27d04b4
proper code formatting
taegyunkim Sep 4, 2025
377b630
code formatting
taegyunkim Sep 4, 2025
8166378
inline formats
taegyunkim Sep 4, 2025
d0c5007
more inline
taegyunkim Sep 4, 2025
0f51076
few more edits to docs
taegyunkim Sep 4, 2025
238a525
lldb instructions
taegyunkim Sep 4, 2025
0921930
this is still relevant to strip debug symbols from release build mode…
taegyunkim Sep 4, 2025
4ae93b0
Merge branch 'main' into taegyunkim/prof-12156-with-debug
taegyunkim Sep 4, 2025
dccf04e
update comment
taegyunkim Sep 4, 2025
76ca29c
Merge branch 'taegyunkim/prof-12156-with-debug' of github.com:DataDog…
taegyunkim Sep 4, 2025
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
16 changes: 16 additions & 0 deletions .github/workflows/build_python_3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,22 @@ jobs:
# `platform.mac_ver()` reports incorrect MacOS version at 11.0
# See: https://stackoverflow.com/a/65402241
CIBW_ENVIRONMENT_MACOS: CMAKE_BUILD_PARALLEL_LEVEL=24 SYSTEM_VERSION_COMPAT=0 CMAKE_ARGS="-DNATIVE_TESTING=OFF"
# cibuildwheel repair will copy anything's under /output directory from the
# build container to the host machine. This is a bit hacky way, but seems
# to be the only way getting debug symbols out from the container while
# we don't mess up with RECORD file.
CIBW_REPAIR_WHEEL_COMMAND_LINUX: |
mkdir -p /output/debugwheelhouse &&
python scripts/extract_debug_symbols.py {wheel} --output-dir /output/debugwheelhouse &&
python scripts/zip_filter.py {wheel} \*.c \*.cpp \*.cc \*.h \*.hpp \*.pyx \*.md &&
mkdir ./tempwheelhouse &&
unzip -l {wheel} | grep '\.so' &&
auditwheel repair -w ./tempwheelhouse {wheel} &&
mv ./tempwheelhouse/*.whl {dest_dir} &&
rm -rf ./tempwheelhouse
CIBW_REPAIR_WHEEL_COMMAND_MACOS: |
mkdir -p ./debugwheelhouse &&
python scripts/extract_debug_symbols.py {wheel} --output-dir ./debugwheelhouse &&
python scripts/zip_filter.py {wheel} \*.c \*.cpp \*.cc \*.h \*.hpp \*.pyx \*.md &&
MACOSX_DEPLOYMENT_TARGET=12.7 delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: python scripts/zip_filter.py "{wheel}" "*.c" "*.cpp" "*.cc" "*.h" "*.hpp" "*.pyx" "*.md" && mv "{wheel}" "{dest_dir}"
Expand Down Expand Up @@ -126,3 +134,11 @@ jobs:
with:
name: wheels-${{ env.ARTIFACT_NAME }}
path: ./wheelhouse/*.whl

- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: runner.os != 'Windows'
with:
name: debug-symbols-${{ env.ARTIFACT_NAME }}
path: |
./debugwheelhouse/*.zip
./wheelhouse/debugwheelhouse/*.zip
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,6 @@ tests/appsec/iast/fixtures/taint_sinks/not_exists.txt
# .env file
.env
.envrc

*.debug
*.dSYM/
2 changes: 1 addition & 1 deletion .gitlab/download-wheels-from-gh-actions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ fi

echo "Github workflow finished. Downloading wheels"
# download all wheels
gh run download $RUN_ID --repo DataDog/dd-trace-py
gh run download $RUN_ID --repo DataDog/dd-trace-py --pattern "wheels-*" --pattern "source-dist*"

cd ..

Expand Down
22 changes: 12 additions & 10 deletions ddtrace/appsec/_iast/_taint_tracking/native.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ static PyMethodDef AspectsMethods[] = {
{ nullptr, nullptr, 0, nullptr }
};

static struct PyModuleDef aspects = { PyModuleDef_HEAD_INIT,
.m_name = PY_MODULE_NAME_ASPECTS,
.m_doc = "Taint tracking Aspects",
.m_size = -1,
.m_methods = AspectsMethods };
// Mark the module as used to prevent it from being stripped.
static struct PyModuleDef aspects __attribute__((used)) = { PyModuleDef_HEAD_INIT,
.m_name = PY_MODULE_NAME_ASPECTS,
.m_doc = "Taint tracking Aspects",
.m_size = -1,
.m_methods = AspectsMethods };

static PyMethodDef OpsMethods[] = {
{ "new_pyobject_id", (PyCFunction)api_new_pyobject_id, METH_FASTCALL, "new pyobject id" },
Expand All @@ -55,11 +56,12 @@ static PyMethodDef OpsMethods[] = {
{ nullptr, nullptr, 0, nullptr }
};

static struct PyModuleDef ops = { PyModuleDef_HEAD_INIT,
.m_name = PY_MODULE_NAME_ASPECTS,
.m_doc = "Taint tracking operations",
.m_size = -1,
.m_methods = OpsMethods };
// Mark the module as used to prevent it from being stripped.
static struct PyModuleDef ops __attribute__((used)) = { PyModuleDef_HEAD_INIT,
.m_name = PY_MODULE_NAME_ASPECTS,
.m_doc = "Taint tracking operations",
.m_size = -1,
.m_methods = OpsMethods };

/**
* This function initializes the native module.
Expand Down
16 changes: 11 additions & 5 deletions ddtrace/internal/datadog/profiling/cmake/AnalysisFunc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ function(add_ddup_config target)
"$<$<CONFIG:RelWithDebInfo>:-Os;-ggdb3>" -fno-semantic-interposition)
endif()

# Common link options
target_link_options(${target} PRIVATE "$<$<CONFIG:RelWithDebInfo>:>")

if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# macOS-specific linker options
target_link_options(${target} PRIVATE "$<$<CONFIG:Release>:-Wl,-dead_strip>")
Expand All @@ -46,11 +43,19 @@ function(add_ddup_config target)
-Wl,--exclude-libs,ALL)
endif()

# If we can IPO, then do so
# If we can IPO, then do so.
check_ipo_supported(RESULT result)

if(result)
set_property(TARGET ${target} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
# When using AppleClang, explicitly use thin LTO to match Rust's thin LTO strategy. And set the object path
# for debug symbols.
target_compile_options(${target} PRIVATE -flto=thin)
target_link_options(${target} PRIVATE -flto=thin)
target_link_options(${target} PRIVATE -Wl,-object_path_lto,${CMAKE_CURRENT_BINARY_DIR}/${target}_lto.o)
else()
set_property(TARGET ${target} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
endif()

# Propagate sanitizers
Expand Down Expand Up @@ -85,4 +90,5 @@ function(add_ddup_config target)
# The main targets, ddup, crashtracker, stack_v2, and dd_wrapper are built as dynamic libraries, so PIC is required.
# And setting this is also fine for tests as they're loading those dynamic libraries.
set_target_properties(${target} PROPERTIES POSITION_INDEPENDENT_CODE ON)

endfunction()
107 changes: 107 additions & 0 deletions docs/debug_symbols.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
Debugging Native Extensions with Debug Symbols
==============================================

dd-trace-py is built with debug symbols by default, and packaged separately from the main wheel files to reduce the size of the primary distribution packages.

Debug Symbol Files
------------------

The project generates debug symbols during the build process:

- **Linux**: ``.debug`` files (using ``objcopy --only-keep-debug``)
- **macOS**: ``.dSYM`` bundles (using ``dsymutil``)

These debug symbols are extracted from the main wheels and packaged into separate `.zip` files with the naming convention:

::

{original-wheel-name}-debug-symbols.zip

For example:

- ``ddtrace-1.20.0-cp39-cp39-linux_x86_64.whl`` → ``ddtrace-1.20.0-cp39-cp39-linux_x86_64-debug-symbols.zip``
- ``ddtrace-1.20.0-cp39-cp39-macosx_10_9_x86_64.whl`` → ``ddtrace-1.20.0-cp39-cp39-macosx_10_9_x86_64-debug-symbols.zip``

Build Process
-------------

The debug symbols are handled automatically during the CI build process:

1. Wheels are built with debug symbols included
2. Debug symbols are extracted using the ``scripts/extract_debug_symbols.py`` script
3. Debug symbols are removed from the main wheel to reduce size
4. Separate debug symbol packages are created and uploaded as artifacts

Usage
-----

To use debug symbols for debugging or crash analysis:

1. Download the appropriate debug symbol package for your platform and Python version
2. Extract the debug symbol files to the same directory as the corresponding `.so` files.
Typically, the site-packages directory where ddtrace is installed.
3. Your debugger or crash analysis tool should automatically find the debug symbols
4. To view assembly with code side by side, you also need the source code, and
set substitute paths in your debugger to the source code directory. For example,
for ``_stack_v2.cpython-313-x86_64-linux-gnu.so`` is compiled from
echion as specified in ``ddtrace/internal/datadog/profiling/stack_v2/CMakeLists.txt``.
So you first need to check out the echion repository and checkout the commit hash.
Then, set substitute paths in gdb to the echion source code directory.
Typically, if you run ``dias /m <symbol>`` in gdb, it will tell you the full
file path of the source code as the following:

.. code-block:: bash

(gdb) disas /m Frame::read
Dump of assembler code for function _ZN5Frame4readEP19_PyInterpreterFramePS1_:
269 /project/build/cmake.linux-x86_64-cpython-313/ddtrace.internal.datadog.profiling.stack_v2._stack_v2/_deps/echion-src/echion/frame.cc: No such file or directory.
0x000000000000ece4 <+0>: push %r12
0x000000000000ece6 <+2>: mov %rdi,%r8
0x000000000000ece9 <+5>: push %rbp
0x000000000000ecea <+6>: mov %rsi,%rbp
0x000000000000eced <+9>: push %rbx
0x000000000000ecee <+10>: sub $0x60,%rsp

270 in /project/build/cmake.linux-x86_64-cpython-313/ddtrace.internal.datadog.profiling.stack_v2._stack_v2/_deps/echion-src/echion/frame.cc
271 in /project/build/cmake.linux-x86_64-cpython-313/ddtrace.internal.datadog.profiling.stack_v2._stack_v2/_deps/echion-src/echion/frame.cc

Then you can set substitute paths in gdb to the echion source code directory

.. code-block:: bash

(gdb) set substitute-path /project/build/cmake.linux-x86_64-cpython-313/ddtrace.internal.datadog.profiling.stack_v2._stack_v2/_deps/echion-src/echion /path/to/echion/source/code

Run ``dias /m Frame::read`` again to see the assembly with code side by side.

.. code-block:: bash

(gdb) disas /m Frame::read
Dump of assembler code for function _ZN5Frame4readEP19_PyInterpreterFramePS1_:
warning: Source file is more recent than executable.
269 {
0x000000000000ece4 <+0>: push %r12
0x000000000000ece6 <+2>: mov %rdi,%r8
0x000000000000ece9 <+5>: push %rbp
0x000000000000ecea <+6>: mov %rsi,%rbp
0x000000000000eced <+9>: push %rbx
0x000000000000ecee <+10>: sub $0x60,%rsp

270 #if PY_VERSION_HEX >= 0x030b0000
271 _PyInterpreterFrame iframe;

272 #if PY_VERSION_HEX >= 0x030d0000
273 // From Python versions 3.13, f_executable can have objects other than
274 // code objects for an internal frame. We need to skip some frames if
275 // its f_executable is not code as suggested here:
276 // https://github.com/python/cpython/issues/100987#issuecomment-1485556487
277 PyObject f_executable;

278
279 for (; frame_addr; frame_addr = frame_addr->previous)
0x000000000000ecf7 <+19>: test %r8,%r8
0x000000000000ecfa <+22>: je 0xed91 <_ZN5Frame4readEP19_PyInterpreterFramePS1_+173>
0x000000000000ed88 <+164>: mov 0x8(%rbx),%r8
0x000000000000ed8c <+168>: jmp 0xecf7 <_ZN5Frame4readEP19_PyInterpreterFramePS1_+19>

On lldb, you can find the source code full path by running ``image lookup -n Frame::read --verbose``,
and set the source code path using ``settings set target.source-map <expected-path> <actual-path>``.
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ Indices and tables
basic_usage
advanced_usage
build_system
debug_symbols
benchmarks
contributing
troubleshooting
Expand Down
4 changes: 3 additions & 1 deletion docs/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ dramatiq
Dramatiq
dsn
dunder
echion
eg
elasticsearch
elasticsearch1
Expand All @@ -116,6 +117,7 @@ flamegraph
fnmatch
formatter
freezegun
gdb
genai
generativeai
gevent
Expand Down Expand Up @@ -340,4 +342,4 @@ wsgi
xfail
yaaredis
openai-agents
validators
validators
Loading
Loading