Skip to content

Commit

Permalink
Emit a .dSYM archive on OSX when generating LLVM debug symbols (cha…
Browse files Browse the repository at this point in the history
…pel-lang#24436)

Resolves chapel-lang#24088.

This PR adjusts LLVM debug symbol generation on OSX to emit a standard
`.dSYM` archive. It also adjusts a test for debug symbols so that it can
run on OSX in addition to linux64.

The archive is created by invoking LLVM's `dsymutil` on the final binary
before it is moved into the user view. In order to get this patch to
work, I had to rewrite `moveResultFromTemp` to consider directories in
addition to files.

TESTING

- [x] `linux64`, `standard`

Reviewed by @jabraham17. Thanks!
  • Loading branch information
dlongnecke-cray authored Feb 20, 2024
2 parents 465080f + 4a9c629 commit 45acf34
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 17 deletions.
55 changes: 46 additions & 9 deletions compiler/llvm/clangUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5120,7 +5120,8 @@ void makeBinaryLLVM(void) {
// to avoid unused argument errors for optimization flags.

if(debugCCode) {
options += " -g";
bool isDarwin = !strcmp(CHPL_TARGET_PLATFORM, "darwin");
options += isDarwin ? "-gfull" : "-g";
}

// We used to supply link args here *and* later on
Expand Down Expand Up @@ -5178,6 +5179,24 @@ void makeBinaryLLVM(void) {
dotOFiles, clangLDArgs);
}

const bool generateDarwinSymArchive =
strcmp(CHPL_TARGET_PLATFORM, "darwin") == 0 &&
debugCCode;

if (generateDarwinSymArchive) {
const char* bin = "dsymutil";
const char* sfx = ".dSYM";
const char* tmp = astr(tmpbinname, sfx);
const char* out = astr(executableFilename, sfx);

// TODO: The innermost binary in the .dSYM with all the DWARF info
// will have the name "executable.tmp", is there a way to give it a
// better name?
std::vector<std::string> cmd = { bin, tmpbinname, "-o", tmp };
mysystem(cmd, "Make Binary - Generating OSX .dSYM Archive");
moveResultFromTmp(out, tmp);
}

// If we're not using a launcher, copy the program here
if (0 == strcmp(CHPL_LAUNCHER, "none")) {

Expand Down Expand Up @@ -5574,18 +5593,36 @@ static void makeLLVMDynamicLibrary(std::string useLinkCXX,
}

static void moveResultFromTmp(const char* resultName, const char* tmpbinname) {
const bool targetExists = llvm::sys::fs::exists(resultName);
bool isTargetDirectory = false;
std::error_code err;

// rm -f hello
if( printSystemCommands )
printf("rm -f %s\n", resultName);
if (targetExists) {
err = llvm::sys::fs::is_directory(tmpbinname, isTargetDirectory);
if (err) {
USR_FATAL("Failed to determine if '%s' is a directory: %s\n",
tmpbinname,
err.message().c_str());
}

err = llvm::sys::fs::remove(resultName);
if (err) {
USR_FATAL("removing file %s failed: %s\n",
resultName,
err.message().c_str());
// Debug message, e.g., 'rm -f hello'
if (printSystemCommands) {
const char* hdr = isTargetDirectory ? "Removing directory: rm -rf"
: "Removing file: rm -f";
printf("%s %s\n", hdr, resultName);
}

err = isTargetDirectory
? llvm::sys::fs::remove_directories(resultName, false)
: llvm::sys::fs::remove(resultName);
if (err) {
const char* hdr = isTargetDirectory
? "Removing directory"
: "Removing file";
USR_FATAL("%s %s failed: %s\n", hdr, resultName, err.message().c_str());
}
}

// mv tmp/hello.tmp hello
if( printSystemCommands )
printf("mv %s %s\n", tmpbinname, resultName);
Expand Down
13 changes: 12 additions & 1 deletion test/llvm/llvmDebug/llvmDebug_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
CHPL_HOST_BIN_SUBDIR=None
CHPL_LLVM_UNIQ_CFG_PATH=None
CHPL_LLVM_CONFIG=None
CHPL_HOST_PLATFORM=None

for line in chplenv.splitlines():
line_str = str(line, encoding='utf-8', errors='surrogateescape')
Expand All @@ -29,11 +30,14 @@
CHPL_LLVM=val
if key == 'CHPL_LLVM_CONFIG':
CHPL_LLVM_CONFIG=val
if key == 'CHPL_HOST_PLATFORM':
CHPL_HOST_PLATFORM=val

build_options = '--baseline -g'
source_path = os.getcwd() #same as target path
source = source_path + os.sep + 'llvmDebug_test.chpl'
target = source_path + os.sep + 'llvmDebug_test'

# Build Chapel Test Program
Command_build = chpl_home + '/bin/' + CHPL_HOST_BIN_SUBDIR + '/chpl ' + build_options + ' ' + source + ' -o ' + target
if os.system(Command_build) == 0:
Expand All @@ -49,8 +53,15 @@
llvm_bin = llvm_bin.strip()
llvm_dwarfdump = llvm_bin + '/llvm-dwarfdump'

dwarfDumpTarget = target

# On OSX we should have built a '.dSYM' archive.
if CHPL_HOST_PLATFORM == 'darwin':
dwarfDumpTarget += '.dSYM' + '/Contents/Resources/DWARF/'
dwarfDumpTarget += 'llvmDebug_test.tmp'

# Check Debug Info Existence
Command_check = llvm_dwarfdump + debug_option + target
Command_check = llvm_dwarfdump + debug_option + dwarfDumpTarget

output_bytes = subprocess.check_output(Command_check, shell=True)
output = str(output_bytes, encoding='utf-8', errors='surrogateescape')
Expand Down
18 changes: 11 additions & 7 deletions test/llvm/llvmDebug/sub_test
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ if [ "$LLVM" = "none" ]; then
exit 0;
fi

if [ "$PLAT" != "linux64" ]; then
echo "[Skipping test based on environment settings]";
exit 0;
fi

#if [ "$PLAT" != "linux64" ]; then
#echo "[Skipping test based on environment settings]";
#exit 0;
#fi

if [ "$COMM" != "none" ]; then
echo "[Skipping test based on environment settings]";
Expand All @@ -26,9 +27,12 @@ fi
rm llvmDebug_test.out.tmp
python3 llvmDebug_test.py "$CHPL_HOME" > llvmDebug_test.out.tmp 2>&1
if ! diff llvmDebug_test.good llvmDebug_test.out.tmp; then
echo "[Error matching debug info for llvmDebug_test]";
echo "[Error matching debug info for llvmDebug_test]";
else
echo "[Success matching debug info for llvmDebug_test]";
rm llvmDebug_test.out.tmp
echo "[Success matching debug info for llvmDebug_test]";
rm llvmDebug_test.out.tmp
if [ "$PLAT" == "darwin" ]; then
rm -rf llvmDebug_test.dSYM
fi
fi
rm llvmDebug_test

0 comments on commit 45acf34

Please sign in to comment.