-
Notifications
You must be signed in to change notification settings - Fork 185
Crash Analyzer Agent #814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Crash Analyzer Agent #814
Conversation
Thanks again for the pushing the code fixing the conflicts, @maoyixie! Before that, let me start an experiment below so that we can see its results together later : ) self.conversation_history.extend(prompt.get()) |
/gcbrun exp -n mx -ag |
agent/crash_analyzer.py
Outdated
@@ -2,7 +2,7 @@ | |||
# | |||
# Licensed under the Apache License, Version 2.0 (the "License"); | |||
# you may not use this file except in compliance with the License. | |||
# You may obtain a copy of the License at | |||
# You may obtain a copy of the License a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo?
agent/crash_analyzer.py
Outdated
with open(os.path.join(generated_project_path, 'Dockerfile'), 'a') as f: | ||
f.write('\nENV FUZZING_LANGUAGE={run_result.benchmark.language}\n' | ||
'\nRUN sed -i.bak \'1i export CFLAGS="${CFLAGS} -g"\' ' | ||
'/src/build.sh\n' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Would it be simpler to modify CFLAGS in dockerfile? E.g.,
ENV CFLAGS="${CFLAGS} -g"
? - Do we need to add
-g
toCXXFLAGS
too?
agent/crash_analyzer.py
Outdated
trial=self.trial) | ||
return prompt_builder.DefaultTemplateBuilder(self.llm).build([]) | ||
|
||
def _create_ossfuzz_project_with_lldb(self, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reckon this function is derived from create_ossfuzz_project()
.
Some nits:
oss_fuzz_checkout.py
is a better place for this function.
That file is designed to encapsulate and handle all OSS-Fuzz related functionalities, so that OSS-Fuzz-Gen does not have to know/consider them. Same with_prepare_project_image()
inLLDBTool
below. We plan to relocatecreate_ossfuzz_project()
too soon.- Please try to avoid code duplication.
We will really appreciate this because if we need to modifycreate_ossfuzz_project()
later, we don't have to remember to repeats the same steps for this function. For example, given your function's main task is appending lines to the Dockerfile, could we first call functioncreate_ossfuzz_project()
to create a new project, then add those new lines to the Dockerfile of the new project?
agent/crash_analyzer.py
Outdated
'\nCOPY agent-build.sh /src/build.sh\n' | ||
'\nENV FUZZING_LANGUAGE={run_result.benchmark.language}\n' | ||
'\nRUN sed -i.bak \'1i export CFLAGS="${CFLAGS} -g"\' /src/build.sh\n' | ||
'\nRUN apt-get update && apt-get install -y lldb\n') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reckon this is another code block we can remove if we first call create_ossfuzz_project()
to create a new project, and then add these lines to the Dockerfile in the new project.
We don't have to worry about agent-build.sh
in that case.
agent/crash_analyzer.py
Outdated
for command in self._parse_tags(response, 'bash'): | ||
prompt_text += self._format_bash_execution_result( | ||
tool.execute(command), previous_prompt=prompt) + '\n' | ||
prompt.add_problem(prompt_text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reckon you overwrite _container_handle_bash_command()
because you want to call add_problem()
instead of append()
for OpenAIPrompt
.
Would it be simpler to implement the append()
function in OpenAIPrompt
so that we don't have to overwrite this function?
This will make the code more transparent between different models and largely lower the complexity when we read/modify the code in the future.
For example:
def append(self, text: str, role:str='user') -> None:
"""Constructs the prompt problem in the required format."""
self._prompt.append({
'role': role,
'content': text,
})
Or append the text to an existing role-content pair, whichever is better.
tool/lldb_tool.py
Outdated
def _prepare_project_image(self) -> str: | ||
"""Prepares the project's OSS-Fuzz docker image and returns the image name. | ||
""" | ||
image_name = f'gcr.io/oss-fuzz/{self.project}' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to use gcr.io/oss-fuzz/{self.project}-lldb
to distinguish it from the normal image without lldb
?
tool/lldb_tool.py
Outdated
logger.info('Successfully build project image for %s', self.project) | ||
return image_name | ||
except sp.CalledProcessError: | ||
logger.info('Failed to build image for %s', self.project) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, would it be clearer to put this in oss_fuzz_checkout
, or reuse some of its code?
Ideally, OSS-Fuzz-Gen, particularly agents, don't have to know OSS-Fuzz details.
tool/lldb_tool.py
Outdated
|
||
def _execute_command(self, | ||
command: list[str], | ||
in_container: bool = False) -> sp.CompletedProcess: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If these functions are the same as _execute_command
and _execute_command_in_container
, could you make lldb_tool
inherit from ProjectContainerTool
so that we don't have to repeat them?
tool/lldb_tool.py
Outdated
result.stderr) | ||
return result | ||
|
||
def _start_docker_container(self) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we reuse
oss-fuzz-gen/tool/container_tool.py
Line 108 in f08dd92
def _start_docker_container(self) -> str: |
tool/lldb_tool.py
Outdated
process.args = command | ||
return process | ||
|
||
def terminate(self) -> bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reuse or inherit from ProjectContainerTool
if possible : )
Hi @maoyixie, the code looks good in general, I've left some comments above, please take a look at your convenience : ) |
def __init__(self, | ||
benchmark: Benchmark, | ||
name: str = '', | ||
project_name: str = '') -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is anything changed here?
tool/container_tool.py
Outdated
super().__init__(benchmark, name) | ||
self.image_name = self._prepare_project_image() | ||
project_name = project_name or benchmark.project |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.project_name
, so that _prepare_project_image
don't have to take this parameter.
Otherwise you need to fix all usages of _prepare_project_image
.
Thanks @maoyixie for the hardwork! |
/gcbrun exp -n mx -ag |
@maoyixie analyzer failed on cloud experiment: Not sure if you have access to cloud build, I will paste the error message below: 2025-03-13 11:31:08 [Trial ID: 02] INFO [logger.info]: Executing Crash Analyzer
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/workspace/ofg/agent/base_agent.py", line 220, in <module>
BaseAgent.cloud_main()
File "/workspace/ofg/agent/base_agent.py", line 206, in cloud_main
result = agent.execute(result_history)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/workspace/ofg/agent/crash_analyzer.py", line 132, in execute
evaluator_lib.Evaluator.create_ossfuzz_project_with_lldb(
File "/workspace/ofg/experiment/evaluator.py", line 332, in create_ossfuzz_project_with_lldb
Evaluator.create_ossfuzz_project(benchmark, name, target_file,
File "/workspace/ofg/experiment/evaluator.py", line 295, in create_ossfuzz_project
shutil.copyfile(
File "/usr/lib/python3.11/shutil.py", line 256, in copyfile
with open(src, 'rb') as fsrc:
^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/experiment/results/output-libfuse-af_gb_alloc_data/fuzz_targets/02.fuzz_target' This is likely due to missing the follow line in your oss-fuzz-gen/agent/prototyper.py Line 428 in a3094bd
This is likely unproducible in local experiments, where those dirs (e.g., |
/gcbrun exp -n mx -ag |
/gcbrun exp -n mx1 -ag |
1 similar comment
/gcbrun exp -n mx1 -ag |
/gcbrun exp -n mx1 -ag |
1 similar comment
/gcbrun exp -n mx1 -ag |
/gcbrun exp -n mx1 -ag |
@maoyixie I have also fixed the chat_llm approach in #902. See if it matches part of the fixing in here. I think either way is good to me since I also see you trying to refractor the model specifically for ChatGPT. @DonggeLiu @DavidKorczynski I am OK with either ways, I will leave #902 in draft until this is merged and see if additional fixes for chat_llm implementation is needed. |
/gcbrun exp -n mx1 -ag |
/gcbrun exp -n mx -ag |
/gcbrun exp -n mx -ag |
Hi @maoyixie, I am unsure if you could see the cloud build error, so I found and pasted it below:
This is likely caused by these lines. |
/gcbrun exp -n my -m vertex_ai_gemini-2-5-pro-chat -ag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exp failed
if not os.path.exists(last_result.artifact_path): | ||
logger.error('Artifact path %s does not exist', | ||
last_result.artifact_path, | ||
trial=self.trial) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good news:
We no longer see the error /workspace/crash-XXXX does not exist
, hence the artifact seems to be correctly uploaded.
Bad news:
This error log was printed:
Already have image (with digest): gcr.io/cloud-builders/docker
2025-05-28 09:29:13 [Trial ID: 00] INFO [logger.info]: Checkign if we should use local FI
2025-05-28 09:29:13 [Trial ID: 00] INFO [logger.info]: This does not require a local FI.
2025-05-28 09:29:13 [Trial ID: 07] INFO [logger.info]: Executing Crash Analyzer
2025-05-28 09:29:13 [Trial ID: 07] ERROR [logger.error]: Artifact path /experiment/results/output-ada-url-ada_can_parse_with_base/artifacts/07.fuzz_target-F0-07/crash-5c013da7b11b7ccb2c437239fbcdbf4c53b20655 does not exist
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/workspace/ofg/agent/base_agent.py", line 280, in <module>
BaseAgent.cloud_main()
File "/workspace/ofg/agent/base_agent.py", line 266, in cloud_main
result = agent.execute(result_history)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/workspace/ofg/agent/crash_analyzer.py", line 172, in execute
evaluator_lib.Evaluator.create_ossfuzz_project_with_lldb(
File "/workspace/ofg/experiment/evaluator.py", line 321, in create_ossfuzz_project_with_lldb
shutil.copyfile(
File "/usr/lib/python3.11/shutil.py", line 256, in copyfile
with open(src, 'rb') as fsrc:
^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/experiment/results/output-ada-url-ada_can_parse_with_base/artifacts/07.fuzz_target-F0-07/crash-5c013da7b11b7ccb2c437239fbcdbf4c53b20655'
Would the artifact be at /workspace/crash-XXXX
, because the cloud build step copied the artifact there and crash analyzer no longer executes self._copy_cloud_artifact(last_result.artifact_path)
?
IIRC, we discussed that it's better to place the artifact at last_result.artifact_path
(in this case, /experiment/results/output-ada-url-ada_can_parse_with_base/artifacts/07.fuzz_target-F0-07/crash-5c013da7b11b7ccb2c437239fbcdbf4c53b20655
), because it is:
- Transparent: It will be the same path for both local and cloud exp.
- Straightforward: we can always trust
last_result.artifact_path
.
Thinking more about this:
Would it be easier to directly download the artifact to last_result.artifact_path
(instead of /workspace/artifact-XXX
) in the cloud build step?
The agent does not need to copy it, it can safely assume the artifact is at last_result.artifact_path
for both local and cloud setup.
We may need to add a step to create the parent dir of last_result.artifact_path
in the cloud build before download it.
f'/workspace/{os.path.basename(artifact_path)}' | ||
], | ||
'allowFailure': True, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, before this step, we have something like:
{
'name':
'gcr.io/cloud-builders/gsutil',
'entrypoint':
'bash',
'args': [
'-c', f'mkdir -p {os.path.dirname(artifact_path)}'
]
},
…ath does not exist
/gcbrun exp -n my -m vertex_ai_gemini-2-5-pro-chat -ag |
/gcbrun exp -n my1 -m vertex_ai_gemini-2-5-pro-chat -ag |
/gcbrun exp -n my -m vertex_ai_gemini-2-5-pro-chat -ag |
… `/workspace` instead.
/gcbrun exp -n my2 -m vertex_ai_gemini-2-5-pro-chat -ag |
/gcbrun exp -n my3 -m vertex_ai_gemini-2-5-pro-chat -ag |
/gcbrun exp -n my4 -m vertex_ai_gemini-2-5-pro-chat -ag |
I will merge this to avoid further conflicts. |
This PR mainly implements a crash analyzer that can interact with LLDB in the multi-agent framework, and supports GPT. In addition, this PR attempts to fix the problem of not replacing the fuzz target and build script. This PR is under testing. The main logic is no longer changing, and minor bugs are being fixed. TODO: Optimize the process of agent interaction with LLDB. Solve the problem of missing debugging information for some projects. Try to add LLM-based static methods to enhance the crash analyzer. --------- Co-authored-by: Dongge Liu <[email protected]>
This PR mainly implements a crash analyzer that can interact with LLDB in the multi-agent framework, and supports GPT. In addition, this PR attempts to fix the problem of not replacing the fuzz target and build script. This PR is under testing. The main logic is no longer changing, and minor bugs are being fixed.
TODO:
Optimize the process of agent interaction with LLDB.
Solve the problem of missing debugging information for some projects.
Try to add LLM-based static methods to enhance the crash analyzer.