diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index dfea5bef..17deda6e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,7 @@ { "name": "R-Dev-Env", "image": "ghcr.io/r-devel/r-dev-env:devel", + "runArgs": ["--cap-add=SYS_PTRACE"], "remoteUser": "vscode", "hostRequirements": { "cpus": 4 @@ -10,8 +11,6 @@ "settings": { "git.ignoredRepositories": ["."], "files.exclude": { - "**/.vscode": true, - "**/.devcontainer": true, "**/.git": true, "**/.github": true, "**/.gitignore": true, @@ -20,8 +19,7 @@ "**/.markdownlint-cli2.yaml": true, "**/.pre-commit-config.yaml": true, "**/Dockerfile": true, - "**/mkdocs.yml": true, - "**/scripts": true + "**/mkdocs.yml": true }, "editor.tabSize": 8, "editor.indentSize": 4, @@ -44,9 +42,10 @@ "johnstoncode.svn-scm", "ms-vscode.cpptools", "MS-vsliveshare.vsliveshare", - "natqe.reload" + "natqe.reload", + "vadimcn.vscode-lldb" ] } }, - "postCreateCommand": "sh /workspaces/r-dev-env/scripts/localscript.sh" + "postCreateCommand": "bash ./scripts/localscript.sh" } diff --git a/.devcontainer/launch.json b/.devcontainer/launch.json new file mode 100644 index 00000000..21090143 --- /dev/null +++ b/.devcontainer/launch.json @@ -0,0 +1,12 @@ +{ +"version": "0.2.0", +"configurations": [ + { + "name": "(lldb) Attach to R", + "type": "lldb", + "request": "attach", + "pid": "${command:pickMyProcess}", + "stopOnEntry": false + } + ] +} diff --git a/docs/tutorials/building_r.md b/docs/tutorials/building_r.md index 85f68146..0f1eab3f 100644 --- a/docs/tutorials/building_r.md +++ b/docs/tutorials/building_r.md @@ -61,8 +61,7 @@ cd $BUILDDIR directory. This step takes ~1 minute on the codespace. ```bash -$TOP_SRCDIR/configure --with-valgrind-instrumentation=1 - +$TOP_SRCDIR/configure --with-valgrind-instrumentation=1 CFLAGS="-g -O0" ``` @@ -71,6 +70,9 @@ $TOP_SRCDIR/configure --with-valgrind-instrumentation=1 of valgrind. See the [Using valgrind](https://cran.r-project.org/doc/manuals/R-exts.html#Using-valgrind) section of the R-admin manual for more information. + The `CFLAGS="-g -O0"` setting compiles C code with debugging symbols + (`-g`) and disables optimization (`-O0`) so the compiled code closely + matches the original source, which aids debugging. - The configure cmd prepares for building R, creating files and folders inside diff --git a/scripts/allow_ptrace.c b/scripts/allow_ptrace.c new file mode 100644 index 00000000..dd85a88a --- /dev/null +++ b/scripts/allow_ptrace.c @@ -0,0 +1,6 @@ +#include +#include + +__attribute__((constructor)) void allow_ptrace() { + prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY); +} diff --git a/scripts/launch_r.sh b/scripts/launch_r.sh new file mode 100644 index 00000000..096669e2 --- /dev/null +++ b/scripts/launch_r.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +export LD_PRELOAD="./scripts/allow_ptrace.so" +# # `which_r.sh` sets the R binary used in the command below +exec /usr/bin/R "$@" diff --git a/scripts/localscript.sh b/scripts/localscript.sh index 083bf016..d345c0e9 100644 --- a/scripts/localscript.sh +++ b/scripts/localscript.sh @@ -27,11 +27,27 @@ cat $WORK_DIR/scripts/welcome_msg.sh >> ~/.bashrc # Remove git directory if it exists #rm -rf .git +# copy launch.json for debugging config if present +if [ -f "$WORK_DIR/.devcontainer/launch.json" ]; then + cp "$WORK_DIR/.devcontainer/launch.json" "$VSCODE_DIR/launch.json" +fi + # copying vscode extension settings from devcontainer json to vscode settings json using jq if [ -f "$DEVCONTAINER_JSON" ]; then jq '.customizations.vscode.settings' "$DEVCONTAINER_JSON" > "$VSCODE_DIR/settings.json" fi +# Update r.rterm.linux setting to use the launch_r.sh script with full dynamic path +if [ -f "$VSCODE_DIR/settings.json" ]; then + tmpfile="${VSCODE_DIR/settings.json}.tmp.$$" + jq --arg rterm "$WORK_DIR/scripts/launch_r.sh" '."r.rterm.linux"=$rterm' "$VSCODE_DIR/settings.json" > "$tmpfile" && mv "$tmpfile" "$VSCODE_DIR/settings.json" +fi + +# Build the ptrace helper library +gcc -shared -fPIC -o "$WORK_DIR/scripts/allow_ptrace.so" "$WORK_DIR/scripts/allow_ptrace.c" + +# Mark the wrapper executable +chmod +x "$WORK_DIR/scripts/launch_r.sh" } diff --git a/scripts/welcome_msg.sh b/scripts/welcome_msg.sh index 00d278e9..c0d724e4 100755 --- a/scripts/welcome_msg.sh +++ b/scripts/welcome_msg.sh @@ -28,9 +28,8 @@ PATCHDIR = \"$PATCHDIR\" Have fun \U0001F601 " -# open INDEX.md if INIT file exists +# open INDEX.md if svn and build directories exist if [ ! -d "svn" ] && [ ! -d "build" ]; then sleep 2 code INDEX.md - rm INIT fi diff --git a/scripts/which_r.sh b/scripts/which_r.sh index 689aecf6..925333ed 100644 --- a/scripts/which_r.sh +++ b/scripts/which_r.sh @@ -59,9 +59,24 @@ which_r() { selected_version="/usr/bin/R" fi + # Define launch script path here where it's actually used + launch_script="$WORK_DIR/scripts/launch_r.sh" + + # Update launch_r.sh to call the selected R binary + if [ -f "$launch_script" ]; then + sed -i "s|^exec [^ ]*/R|exec $selected_version|" "$launch_script" + else + echo "Warning: launch_r.sh script not found, skipping update." + fi + # Update settings.json with the chosen R path - updated_settings_data=$(cat "$settings_file_path" | jq --arg subdir "$selected_version" '."r.rterm.linux"=$subdir | ."r.rpath.linux"=$subdir') - echo "$updated_settings_data" > "$settings_file_path" + if [ -f "$settings_file_path" ]; then + tmpfile="${settings_file_path}.tmp.$$" + jq --arg r "$selected_version" '."r.rpath.linux"=$r' "$settings_file_path" > "$tmpfile" && mv "$tmpfile" "$settings_file_path" + else + echo "Warning: VS Code settings.json not found, skipping update." + fi + echo "R terminal will now use version: $selected_version" echo "To update the HTML help, click \"Reload\" in the VS Code status bar (bottom right) to reload your VS Code window."