diff --git a/pythonbpf/debuginfo/debug_info_generator.py b/pythonbpf/debuginfo/debug_info_generator.py index 5d10855..7d319ba 100644 --- a/pythonbpf/debuginfo/debug_info_generator.py +++ b/pythonbpf/debuginfo/debug_info_generator.py @@ -200,4 +200,37 @@ class DebugInfoGenerator: type_array.append(param_types) return self.module.add_debug_info("DISubroutineType", {"types": type_array}) + def create_local_variable_debug_info( + self, name: str, arg: int, var_type: Any + ) -> Any: + """ + Create debug info for a local variable (DILocalVariable) without scope. + Example: + !DILocalVariable(name: "ctx", arg: 1, file: !3, line: 20, type: !7) + """ + return self.module.add_debug_info( + "DILocalVariable", + { + "name": name, + "arg": arg, + "file": self.module._file_metadata, + "type": var_type, + }, + ) + def add_scope_to_local_variable(self, local_variable_debug_info, scope_value): + """ + Add scope information to an existing local variable debug info object. + """ + #TODO: this is a workaround a flaw in the debug info generation. Fix this if possible in the future. + # We should not be touching llvmlite's internals like this. + if hasattr(local_variable_debug_info, 'operands'): + # LLVM metadata operands is a tuple, so we need to rebuild it + existing_operands = local_variable_debug_info.operands + + # Convert tuple to list, add scope, convert back to tuple + operands_list = list(existing_operands) + operands_list.append(('scope', scope_value)) + + # Reassign the new tuple + local_variable_debug_info.operands = tuple(operands_list) \ No newline at end of file diff --git a/pythonbpf/functions/function_debug_info.py b/pythonbpf/functions/function_debug_info.py index e7f49ef..482f228 100644 --- a/pythonbpf/functions/function_debug_info.py +++ b/pythonbpf/functions/function_debug_info.py @@ -49,8 +49,18 @@ def generate_function_debug_info( "The first argument should always be a pointer to a struct or a void pointer" ) context_debug_info = VmlinuxHandlerRegistry.get_struct_debug_info(annotation.id) - pointer_to_context_debug_info = generator.create_pointer_type(context_debug_info, 64) - subroutine_type = generator.create_subroutine_type(return_type, pointer_to_context_debug_info) - print(subroutine_type) + pointer_to_context_debug_info = generator.create_pointer_type( + context_debug_info, 64 + ) + subroutine_type = generator.create_subroutine_type( + return_type, pointer_to_context_debug_info + ) + context_local_variable = generator.create_local_variable_debug_info( + leading_argument_name, 1, pointer_to_context_debug_info + ) + + # following is just a test. + generator.add_scope_to_local_variable(context_local_variable, module._file_metadata) + print(context_local_variable) else: logger.error(f"Invalid annotation type for argument '{leading_argument_name}'")