1# REQUIRES: curl, httplib, thread_support 2 3#int main () { 4# int x = 1; 5# return x; 6#} 7# 8#Build as : clang -g main.c -o main-debug.exe 9#Then run : cp main-debug.exe main.exe && strip main.exe 10#resulting buildid: 2c39b7557c50162aaeb5a3148c9f76e6e46012e3 11 12# RUN: rm -rf %t 13# RUN: mkdir %t 14# # Query the debuginfod server for artifacts 15# RUN: DEBUGINFOD_CACHE_PATH=%t %python %s --server-cmd 'llvm-debuginfod -v -c 3 %S/Inputs' \ 16# RUN: --tool-cmd 'llvm-debuginfod-find --dump --executable 2c39b7557c50162aaeb5a3148c9f76e6e46012e3' | \ 17# RUN: diff - %S/Inputs/main.exe 18# RUN: DEBUGINFOD_CACHE_PATH=%t %python %s --server-cmd 'llvm-debuginfod -v -c 3 %S/Inputs' \ 19# RUN: --tool-cmd 'llvm-debuginfod-find --dump --debuginfo 2c39b7557c50162aaeb5a3148c9f76e6e46012e3' | \ 20# RUN: diff - %S/Inputs/main-debug.exe 21# Debuginfod server does not yet support source files 22 23# # The artifacts should still be present in the cache without needing to query 24# # the server. 25# RUN: DEBUGINFOD_CACHE_PATH=%t llvm-debuginfod-find --dump \ 26# RUN: --executable 2c39b7557c50162aaeb5a3148c9f76e6e46012e3 | \ 27# RUN: diff - %S/Inputs/main.exe 28# RUN: DEBUGINFOD_CACHE_PATH=%t llvm-debuginfod-find --dump \ 29# RUN: --debuginfo 2c39b7557c50162aaeb5a3148c9f76e6e46012e3 | \ 30# RUN: diff - %S/Inputs/main-debug.exe 31 32 33 34# This script is used to test the debuginfod client within a host tool against 35# the debuginfod server. 36# It first stands up the debuginfod server and then executes the tool. 37# This way the tool can make debuginfod HTTP requests to the debuginfod server. 38import argparse 39import threading 40import subprocess 41import sys 42import os 43import io 44 45# Starts the server and obtains the port number from the first line of stdout. 46# Waits until the server has completed one full directory scan before returning. 47def start_debuginfod_server(server_args): 48 process = subprocess.Popen( 49 server_args, 50 env=os.environ, 51 stdout=subprocess.PIPE) 52 port = -1 53 # Obtain the port. 54 stdout_reader = io.TextIOWrapper(process.stdout, encoding='ascii') 55 stdout_line = stdout_reader.readline() 56 port = int(stdout_line.split()[-1]) 57 # Wait until a directory scan is completed. 58 while True: 59 stdout_line = stdout_reader.readline().strip() 60 print(stdout_line, file=sys.stderr) 61 if stdout_line == 'Updated collection': 62 break 63 return (process, port) 64 65# Starts the server with the specified args (if nonempty), then runs the tool 66# with specified args. 67# Sets the DEBUGINFOD_CACHE_PATH env var to point at the given cache_directory. 68# Sets the DEBUGINFOD_URLS env var to point at the local server. 69def test_tool(server_args, tool_args): 70 server_process = None 71 client_process = None 72 port = None 73 server_process, port = start_debuginfod_server(server_args) 74 try: 75 env = os.environ 76 if port is not None: 77 env['DEBUGINFOD_URLS'] = 'http://localhost:%s' % port 78 client_process = subprocess.Popen( 79 tool_args, env=os.environ) 80 client_code = client_process.wait() 81 if client_code != 0: 82 print('nontrivial client return code %s' % client_code, file=sys.stderr) 83 return 1 84 if server_process is not None: 85 server_process.terminate() 86 server_code = server_process.wait() 87 if server_code != -15: 88 print('nontrivial server return code %s' % server_code, file=sys.stderr) 89 return 1 90 91 finally: 92 if server_process is not None: 93 server_process.terminate() 94 if client_process is not None: 95 client_process.terminate() 96 return 0 97 98def main(): 99 parser = argparse.ArgumentParser() 100 parser.add_argument('--server-cmd', default='', help='Command to start the server. If not present, no server is started.', type=str) 101 parser.add_argument('--tool-cmd', required=True, type=str) 102 args = parser.parse_args() 103 result = test_tool(args.server_cmd.split(), 104 args.tool_cmd.split()) 105 sys.exit(result) 106 107if __name__ == '__main__': 108 main() 109