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