TranslationUnit[0:0->150:0] VariableDeclaration[0:0->2:0] NamedType[0:0->0:9] [static] int g_pid UnaryExpression[0:19->0:20] - NumericLiteral[0:20->0:20] 1 FunctionDeclaration[2:0->10:0] [static] NamedType[2:7->2:10] void handle_sigint ( Parameter[2:26->2:28] NamedType[2:26->2:28] int ) FunctionDefinition[3:0->10:0] { IfStatement[4:4->5:14] Predicate: BinaryExpression[4:8->4:18] Name[4:8->4:12] g_pid == UnaryExpression[4:17->4:18] - NumericLiteral[4:18->4:18] 1 Then: ReturnStatement[5:8->5:14] IfStatement[7:4->10:0] Predicate: BinaryExpression[7:8->7:43] FunctionCall[7:8->7:39] Name[7:8->7:13] ptrace Name[7:15->7:23] PT_DETACH Name[7:26->7:30] g_pid NumericLiteral[7:33->7:33] 0 NumericLiteral[7:36->7:36] 0 == UnaryExpression[7:42->7:43] - NumericLiteral[7:43->7:43] 1 Then: BlockStatement[7:46->10:0] FunctionCall[8:8->8:24] Name[8:8->8:13] perror StringLiteral[8:15->8:22] "detach" } FunctionDeclaration[12:0->150:0] NamedType[12:0->12:2] int main ( Parameter[12:9->12:16] argc NamedType[12:9->12:11] int Parameter[12:19->12:29] argv Pointer[12:19->12:24] Pointer[12:19->12:24] NamedType[12:19->12:23] char ) FunctionDefinition[13:0->150:0] { IfStatement[14:4->19:4] Predicate: BinaryExpression[14:8->14:74] FunctionCall[14:8->14:72] Name[14:8->14:13] pledge StringLiteral[14:15->14:60] "stdio wpath cpath proc exec ptrace sigaction" NullPointerLiteral[14:63->14:69] < NumericLiteral[14:74->14:74] 0 Then: BlockStatement[14:77->19:4] FunctionCall[15:8->15:24] Name[15:8->15:13] perror StringLiteral[15:15->15:22] "pledge" ReturnStatement[16:8->16:16] NumericLiteral[16:15->16:15] 1 VariableDeclaration[19:4->19:34] NamedType[19:4->19:22] Vector<[const] char*> child_argv VariableDeclaration[21:4->21:41] Pointer[21:4->21:14] NamedType[21:4->21:14] [const] char output_filename NullPointerLiteral[21:34->21:40] VariableDeclaration[22:4->22:59] NamedType[22:4->22:7] auto trace_file_or_error FunctionCall[22:31->22:59] Name[22:31->22:56] Core::File::standard_error IfStatement[23:4->27:4] Predicate: FunctionCall[23:8->23:38] MemberExpression[23:8->23:36] Name[23:8->23:26] trace_file_or_error Identifier[23:28->23:35] is_error Then: BlockStatement[23:40->27:4] FunctionCall[24:8->24:79] Name[24:8->24:12] outln Name[24:14->24:19] stderr StringLiteral[24:22->24:48] "Failed to open stderr: {}" FunctionCall[24:51->24:78] MemberExpression[24:51->24:76] Name[24:51->24:69] trace_file_or_error Identifier[24:71->24:75] error ReturnStatement[25:8->25:16] NumericLiteral[25:15->25:15] 1 VariableDeclaration[27:4->27:57] NamedType[27:4->27:7] auto trace_file FunctionCall[27:22->27:57] MemberExpression[27:22->27:55] Name[27:22->27:40] trace_file_or_error Identifier[27:42->27:54] release_value VariableDeclaration[29:4->29:27] NamedType[29:4->29:19] Core::ArgsParser parser FunctionCall[30:4->31:47] MemberExpression[30:4->30:27] Name[30:4->30:9] parser Identifier[30:11->30:26] set_general_help StringLiteral[31:8->31:45] "Trace all syscalls and their result." FunctionCall[32:4->32:70] MemberExpression[32:4->32:21] Name[32:4->32:9] parser Identifier[32:11->32:20] add_option Name[32:22->32:26] g_pid StringLiteral[32:29->32:49] "Trace the given PID" StringLiteral[32:52->32:56] "pid" StringLiteral[32:59->32:61] 'p' StringLiteral[32:64->32:68] "pid" FunctionCall[33:4->33:94] MemberExpression[33:4->33:21] Name[33:4->33:9] parser Identifier[33:11->33:20] add_option Name[33:22->33:36] output_filename StringLiteral[33:39->33:67] "Filename to write output to" StringLiteral[33:70->33:77] "output" StringLiteral[33:80->33:82] 'o' StringLiteral[33:85->33:92] "output" FunctionCall[34:4->34:111] MemberExpression[34:4->34:34] Name[34:4->34:9] parser Identifier[34:11->34:33] add_positional_argument Name[34:35->34:44] child_argv StringLiteral[34:47->34:65] "Arguments to exec" StringLiteral[34:68->34:77] "argument" Name[34:80->34:109] Core::ArgsParser::Required::No FunctionCall[36:4->36:28] MemberExpression[36:4->36:16] Name[36:4->36:9] parser Identifier[36:11->36:15] parse Name[36:17->36:20] argc Name[36:23->36:26] argv IfStatement[38:4->47:4] Predicate: BinaryExpression[38:8->38:33] Name[38:8->38:22] output_filename != NullPointerLiteral[38:27->38:33] Then: BlockStatement[38:36->47:4] VariableDeclaration[39:8->39:89] NamedType[39:8->39:11] auto open_result FunctionCall[39:27->39:89] Name[39:27->39:42] Core::File::open Name[39:44->39:58] output_filename Name[39:61->39:87] Core::File::OpenMode::Write IfStatement[40:8->44:8] Predicate: FunctionCall[40:12->40:34] MemberExpression[40:12->40:32] Name[40:12->40:22] open_result Identifier[40:24->40:31] is_error Then: BlockStatement[40:36->44:8] FunctionCall[41:12->41:80] Name[41:12->41:16] outln Name[41:18->41:23] stderr StringLiteral[41:26->41:57] "Failed to open output file: {}" FunctionCall[41:60->41:79] MemberExpression[41:60->41:77] Name[41:60->41:70] open_result Identifier[41:72->41:76] error ReturnStatement[42:12->42:20] NumericLiteral[42:19->42:19] 1 AssignmentExpression[44:8->44:48] Name[44:8->44:17] trace_file = FunctionCall[44:21->44:48] MemberExpression[44:21->44:46] Name[44:21->44:31] open_result Identifier[44:33->44:45] release_value IfStatement[47:4->52:4] Predicate: BinaryExpression[47:8->47:62] FunctionCall[47:8->47:60] Name[47:8->47:13] pledge StringLiteral[47:15->47:48] "stdio proc exec ptrace sigaction" NullPointerLiteral[47:51->47:57] < NumericLiteral[47:62->47:62] 0 Then: BlockStatement[47:65->52:4] FunctionCall[48:8->48:24] Name[48:8->48:13] perror StringLiteral[48:15->48:22] "pledge" ReturnStatement[49:8->49:16] NumericLiteral[49:15->49:15] 1 VariableDeclaration[52:4->52:14] NamedType[52:4->52:6] int status IfStatement[53:4->86:4] Predicate: BinaryExpression[53:8->53:18] Name[53:8->53:12] g_pid == UnaryExpression[53:17->53:18] - NumericLiteral[53:18->53:18] 1 Then: BlockStatement[53:21->86:4] IfStatement[54:8->59:8] Predicate: FunctionCall[54:12->54:33] MemberExpression[54:12->54:31] Name[54:12->54:21] child_argv Identifier[54:23->54:30] is_empty Then: BlockStatement[54:35->59:8] FunctionCall[55:12->55:78] Name[55:12->55:16] outln Name[55:18->55:23] stderr StringLiteral[55:26->55:76] "strace: Expected either a pid or some arguments\n" ReturnStatement[56:12->56:20] NumericLiteral[56:19->56:19] 1 FunctionCall[59:8->59:34] MemberExpression[59:8->59:25] Name[59:8->59:17] child_argv Identifier[59:19->59:24] append NullPointerLiteral[59:26->59:32] VariableDeclaration[60:8->60:24] NamedType[60:8->60:10] int pid FunctionCall[60:18->60:24] Name[60:18->60:21] fork IfStatement[61:8->66:8] Predicate: BinaryExpression[61:12->61:18] Name[61:12->61:14] pid < NumericLiteral[61:18->61:18] 0 Then: BlockStatement[61:21->66:8] FunctionCall[62:12->62:26] Name[62:12->62:17] perror StringLiteral[62:19->62:24] "fork" ReturnStatement[63:12->63:20] NumericLiteral[63:19->63:19] 1 IfStatement[66:8->79:8] Predicate: UnaryExpression[66:12->66:15] ! Name[66:13->66:15] pid Then: BlockStatement[66:18->79:8] IfStatement[67:12->71:12] Predicate: BinaryExpression[67:16->67:49] FunctionCall[67:16->67:45] Name[67:16->67:21] ptrace Name[67:23->67:33] PT_TRACE_ME NumericLiteral[67:36->67:36] 0 NumericLiteral[67:39->67:39] 0 NumericLiteral[67:42->67:42] 0 == UnaryExpression[67:48->67:49] - NumericLiteral[67:49->67:49] 1 Then: BlockStatement[67:52->71:12] FunctionCall[68:16->68:33] Name[68:16->68:21] perror StringLiteral[68:23->68:31] "traceme" ReturnStatement[69:16->69:24] NumericLiteral[69:23->69:23] 1 VariableDeclaration[71:12->71:86] NamedType[71:12->71:14] int rc FunctionCall[71:21->71:86] Name[71:21->71:26] execvp FunctionCall[71:28->71:46] MemberExpression[71:28->71:44] Name[71:28->71:37] child_argv Identifier[71:39->71:43] first CppCastExpression[71:48->71:85] const_cast < Pointer[71:59->71:64] Pointer[71:59->71:64] NamedType[71:59->71:63] char > FunctionCall[71:67->71:84] MemberExpression[71:67->71:82] Name[71:67->71:76] child_argv Identifier[71:78->71:81] data IfStatement[72:12->76:12] Predicate: BinaryExpression[72:16->72:21] Name[72:16->72:17] rc < NumericLiteral[72:21->72:21] 0 Then: BlockStatement[72:24->76:12] FunctionCall[73:16->73:32] Name[73:16->73:21] perror StringLiteral[73:23->73:30] "execvp" FunctionCall[74:16->74:23] Name[74:16->74:19] exit NumericLiteral[74:21->74:21] 1 FunctionCall[76:12->76:32] Name[76:12->76:29] VERIFY_NOT_REACHED AssignmentExpression[79:8->79:18] Name[79:8->79:12] g_pid = Name[79:16->79:18] pid IfStatement[80:8->84:4] Predicate: BinaryExpression[80:12->80:83] FunctionCall[80:12->80:54] Name[80:12->80:18] waitpid Name[80:20->80:22] pid UnaryExpression[80:25->80:31] & Name[80:26->80:31] status BinaryExpression[80:34->80:51] Name[80:34->80:41] WSTOPPED | Name[80:45->80:51] WEXITED != BinaryExpression[80:57->80:83] Name[80:57->80:59] pid || UnaryExpression[80:64->80:83] ! FunctionCall[80:65->80:83] Name[80:65->80:74] WIFSTOPPED Name[80:76->80:81] status Then: BlockStatement[80:85->84:4] FunctionCall[81:12->81:29] Name[81:12->81:17] perror StringLiteral[81:19->81:27] "waitpid" ReturnStatement[82:12->82:20] NumericLiteral[82:19->82:19] 1 VariableDeclaration[86:4->86:23] NamedType[86:4->86:19] sigaction sa FunctionCall[87:4->87:44] Name[87:4->87:9] memset UnaryExpression[87:11->87:13] & Name[87:12->87:13] sa NumericLiteral[87:16->87:16] 0 SizeofExpression[87:19->87:43] NamedType[87:26->87:41] sigaction AssignmentExpression[88:4->88:32] MemberExpression[88:4->88:18] Name[88:4->88:5] sa Identifier[88:7->88:16] sa_handler = Name[88:20->88:32] handle_sigint FunctionCall[89:4->89:35] Name[89:4->89:12] sigaction Name[89:14->89:19] SIGINT UnaryExpression[89:22->89:24] & Name[89:23->89:24] sa NullPointerLiteral[89:27->89:33] IfStatement[91:4->95:4] Predicate: BinaryExpression[91:8->91:43] FunctionCall[91:8->91:39] Name[91:8->91:13] ptrace Name[91:15->91:23] PT_ATTACH Name[91:26->91:30] g_pid NumericLiteral[91:33->91:33] 0 NumericLiteral[91:36->91:36] 0 == UnaryExpression[91:42->91:43] - NumericLiteral[91:43->91:43] 1 Then: BlockStatement[91:46->95:4] FunctionCall[92:8->92:24] Name[92:8->92:13] perror StringLiteral[92:15->92:22] "attach" ReturnStatement[93:8->93:16] NumericLiteral[93:15->93:15] 1 IfStatement[95:4->100:4] Predicate: BinaryExpression[95:8->95:83] FunctionCall[95:8->95:52] Name[95:8->95:14] waitpid Name[95:16->95:20] g_pid UnaryExpression[95:23->95:29] & Name[95:24->95:29] status BinaryExpression[95:32->95:49] Name[95:32->95:39] WSTOPPED | Name[95:43->95:49] WEXITED != BinaryExpression[95:55->95:83] Name[95:55->95:59] g_pid || UnaryExpression[95:64->95:83] ! FunctionCall[95:65->95:83] Name[95:65->95:74] WIFSTOPPED Name[95:76->95:81] status Then: BlockStatement[95:85->100:4] FunctionCall[96:8->96:25] Name[96:8->96:13] perror StringLiteral[96:15->96:23] "waitpid" ReturnStatement[97:8->97:16] NumericLiteral[97:15->97:15] 1 ForStatement[100:4->149:4] BlockStatement[100:13->149:4] IfStatement[101:8->105:8] Predicate: BinaryExpression[101:12->101:48] FunctionCall[101:12->101:44] Name[101:12->101:17] ptrace Name[101:19->101:28] PT_SYSCALL Name[101:31->101:35] g_pid NumericLiteral[101:38->101:38] 0 NumericLiteral[101:41->101:41] 0 == UnaryExpression[101:47->101:48] - NumericLiteral[101:48->101:48] 1 Then: BlockStatement[101:51->105:8] FunctionCall[102:12->102:29] Name[102:12->102:17] perror StringLiteral[102:19->102:27] "syscall" ReturnStatement[103:12->103:20] NumericLiteral[103:19->103:19] 1 IfStatement[105:8->109:8] Predicate: BinaryExpression[105:12->105:87] FunctionCall[105:12->105:56] Name[105:12->105:18] waitpid Name[105:20->105:24] g_pid UnaryExpression[105:27->105:33] & Name[105:28->105:33] status BinaryExpression[105:36->105:53] Name[105:36->105:43] WSTOPPED | Name[105:47->105:53] WEXITED != BinaryExpression[105:59->105:87] Name[105:59->105:63] g_pid || UnaryExpression[105:68->105:87] ! FunctionCall[105:69->105:87] Name[105:69->105:78] WIFSTOPPED Name[105:80->105:85] status Then: BlockStatement[105:89->109:8] FunctionCall[106:12->106:30] Name[106:12->106:17] perror StringLiteral[106:19->106:28] "wait_pid" ReturnStatement[107:12->107:20] NumericLiteral[107:19->107:19] 1 VariableDeclaration[109:8->109:33] NamedType[109:8->109:22] PtraceRegisters regs BracedInitList[109:31->109:33] IfStatement[110:8->114:8] Predicate: BinaryExpression[110:12->110:52] FunctionCall[110:12->110:48] Name[110:12->110:17] ptrace Name[110:19->110:28] PT_GETREGS Name[110:31->110:35] g_pid UnaryExpression[110:38->110:42] & Name[110:39->110:42] regs NumericLiteral[110:45->110:45] 0 == UnaryExpression[110:51->110:52] - NumericLiteral[110:52->110:52] 1 Then: BlockStatement[110:55->114:8] FunctionCall[111:12->111:29] Name[111:12->111:17] perror StringLiteral[111:19->111:27] "getregs" ReturnStatement[112:12->112:20] NumericLiteral[112:19->112:19] 1 VariableDeclaration[114:8->114:36] NamedType[114:8->114:10] u32 syscall_index MemberExpression[114:28->114:36] Name[114:28->114:31] regs Identifier[114:33->114:35] eax VariableDeclaration[115:8->115:27] NamedType[115:8->115:10] u32 arg1 MemberExpression[115:19->115:27] Name[115:19->115:22] regs Identifier[115:24->115:26] edx VariableDeclaration[116:8->116:27] NamedType[116:8->116:10] u32 arg2 MemberExpression[116:19->116:27] Name[116:19->116:22] regs Identifier[116:24->116:26] ecx VariableDeclaration[117:8->117:27] NamedType[117:8->117:10] u32 arg3 MemberExpression[117:19->117:27] Name[117:19->117:22] regs Identifier[117:24->117:26] ebx IfStatement[119:8->123:8] Predicate: BinaryExpression[119:12->119:48] FunctionCall[119:12->119:44] Name[119:12->119:17] ptrace Name[119:19->119:28] PT_SYSCALL Name[119:31->119:35] g_pid NumericLiteral[119:38->119:38] 0 NumericLiteral[119:41->119:41] 0 == UnaryExpression[119:47->119:48] - NumericLiteral[119:48->119:48] 1 Then: BlockStatement[119:51->123:8] FunctionCall[120:12->120:29] Name[120:12->120:17] perror StringLiteral[120:19->120:27] "syscall" ReturnStatement[121:12->121:20] NumericLiteral[121:19->121:19] 1 IfStatement[123:8->128:8] Predicate: BinaryExpression[123:12->123:87] FunctionCall[123:12->123:56] Name[123:12->123:18] waitpid Name[123:20->123:24] g_pid UnaryExpression[123:27->123:33] & Name[123:28->123:33] status BinaryExpression[123:36->123:53] Name[123:36->123:43] WSTOPPED | Name[123:47->123:53] WEXITED != BinaryExpression[123:59->123:87] Name[123:59->123:63] g_pid || UnaryExpression[123:68->123:87] ! FunctionCall[123:69->123:87] Name[123:69->123:78] WIFSTOPPED Name[123:80->123:85] status Then: BlockStatement[123:89->128:8] FunctionCall[124:12->124:30] Name[124:12->124:17] perror StringLiteral[124:19->124:28] "wait_pid" ReturnStatement[125:12->125:20] NumericLiteral[125:19->125:19] 1 IfStatement[128:8->133:8] Predicate: BinaryExpression[128:12->128:52] FunctionCall[128:12->128:48] Name[128:12->128:17] ptrace Name[128:19->128:28] PT_GETREGS Name[128:31->128:35] g_pid UnaryExpression[128:38->128:42] & Name[128:39->128:42] regs NumericLiteral[128:45->128:45] 0 == UnaryExpression[128:51->128:52] - NumericLiteral[128:52->128:52] 1 Then: BlockStatement[128:55->133:8] FunctionCall[129:12->129:29] Name[129:12->129:17] perror StringLiteral[129:19->129:27] "getregs" ReturnStatement[130:12->130:20] NumericLiteral[130:19->130:19] 1 VariableDeclaration[133:8->133:26] NamedType[133:8->133:10] u32 res MemberExpression[133:18->133:26] Name[133:18->133:21] regs Identifier[133:23->133:25] eax VariableDeclaration[135:8->140:16] NamedType[135:8->135:11] auto string FunctionCall[135:22->140:16] Name[135:22->135:38] String::formatted StringLiteral[135:40->135:77] "{}({:#08x}, {:#08x}, {:#08x})\t={}\n" FunctionCall[136:12->136:64] Name[136:12->136:29] Syscall::to_string CStyleCastExpression[136:31->136:63] NamedType[136:32->136:48] Syscall::Function Name[136:50->136:62] syscall_index Name[137:12->137:15] arg1 Name[138:12->138:15] arg2 Name[139:12->139:15] arg3 Name[140:12->140:14] res VariableDeclaration[142:8->142:53] NamedType[142:8->142:11] auto result BinaryExpression[142:22->142:53] Name[142:22->142:31] trace_file -> FunctionCall[142:34->142:53] Name[142:34->142:44] write_value Name[142:46->142:51] string IfStatement[143:8->147:4] Predicate: FunctionCall[143:12->143:29] MemberExpression[143:12->143:27] Name[143:12->143:17] result Identifier[143:19->143:26] is_error Then: BlockStatement[143:31->147:4] FunctionCall[144:12->144:48] Name[144:12->144:17] warnln StringLiteral[144:19->144:29] "write: {}" BinaryExpression[144:32->144:47] Name[144:32->144:37] result -> FunctionCall[144:40->144:47] Name[144:40->144:44] error ReturnStatement[145:12->145:20] NumericLiteral[145:19->145:19] 1 ReturnStatement[149:4->149:12] NumericLiteral[149:11->149:11] 0 }