30
30
from results import AnalysisResult , CrashResult , Result , RunResult
31
31
from tool .base_tool import BaseTool
32
32
from tool .container_tool import ProjectContainerTool
33
- from tool .lldb_tool import LLDBTool
33
+ from tool .gdb_tool import GDBTool
34
34
35
35
MAX_ROUND = 100
36
36
@@ -66,31 +66,39 @@ def _initial_prompt(self, results: list[Result]) -> Prompt:
66
66
trial = self .trial )
67
67
return prompt_builder .CrashAnalyzerTemplateBuilder (self .llm ).build ([])
68
68
69
- def _format_lldb_execution_result (
69
+ def _format_gdb_execution_result (
70
70
self ,
71
- lldb_command : str ,
71
+ gdb_command : str ,
72
72
process : sp .CompletedProcess ,
73
73
previous_prompt : Optional [Prompt ] = None ) -> str :
74
- """Formats a prompt based on lldb execution result."""
74
+ """Formats a prompt based on gdb execution result."""
75
75
if previous_prompt :
76
76
previous_prompt_text = previous_prompt .get ()
77
77
else :
78
78
previous_prompt_text = ''
79
- stdout = self .llm .truncate_prompt (process .stdout ,
79
+
80
+ raw_lines = process .stdout .strip ().splitlines ()
81
+ if raw_lines and raw_lines [- 1 ].strip ().startswith ("(gdb)" ):
82
+ raw_lines .pop ()
83
+ if raw_lines :
84
+ raw_lines [0 ] = f'(gdb) { raw_lines [0 ].strip ()} '
85
+ processed_stdout = '\n ' .join (raw_lines )
86
+
87
+ stdout = self .llm .truncate_prompt (processed_stdout ,
80
88
previous_prompt_text ).strip ()
81
89
stderr = self .llm .truncate_prompt (process .stderr ,
82
90
stdout + previous_prompt_text ).strip ()
83
- return (f'<lldb command>\n { lldb_command .strip ()} \n </lldb command>\n '
84
- f'<lldb output>\n { stdout } \n </lldb output>\n '
91
+ return (f'<gdb command>\n { gdb_command .strip ()} \n </gdb command>\n '
92
+ f'<gdb output>\n { stdout } \n </gdb output>\n '
85
93
f'<stderr>\n { stderr } \n </stderr>\n ' )
86
94
87
- def _container_handle_lldb_command (self , response : str , tool : LLDBTool ,
88
- prompt : Prompt ) -> Prompt :
89
- """Handles the command from LLM with lldb tool."""
95
+ def _container_handle_gdb_command (self , response : str , tool : GDBTool ,
96
+ prompt : Prompt ) -> Prompt :
97
+ """Handles the command from LLM with gdb tool."""
90
98
prompt_text = ''
91
- for command in self ._parse_tags (response , 'lldb ' ):
99
+ for command in self ._parse_tags (response , 'gdb ' ):
92
100
process = tool .execute_in_screen (command )
93
- prompt_text += self ._format_lldb_execution_result (
101
+ prompt_text += self ._format_gdb_execution_result (
94
102
command , process , previous_prompt = prompt ) + '\n '
95
103
prompt .append (prompt_text )
96
104
return prompt
@@ -103,9 +111,9 @@ def _container_handle_conclusion(self, cur_round: int, response: str,
103
111
trial = self .trial )
104
112
105
113
conclusion = self ._parse_tag (response , 'conclusion' )
106
- if conclusion == 'Crash is caused by bug in fuzz driver. ' :
114
+ if conclusion == 'False ' :
107
115
crash_result .true_bug = False
108
- elif conclusion == 'Crash is caused by bug in project. ' :
116
+ elif conclusion == 'True ' :
109
117
crash_result .true_bug = True
110
118
else :
111
119
logger .error ('***** Failed to match conclusion in %02d rounds *****' ,
@@ -127,11 +135,10 @@ def _container_tool_reaction(self, cur_round: int, response: str,
127
135
crash_result )
128
136
prompt = prompt_builder .CrashAnalyzerTemplateBuilder (self .llm ,
129
137
None ).build ([])
130
- if self ._parse_tag (response , 'lldb' ):
131
- return self ._container_handle_lldb_command (response , self .analyze_tool ,
132
- prompt )
138
+ if self ._parse_tag (response , 'gdb' ):
139
+ return self ._container_handle_gdb_command (response , self .gdb_tool , prompt )
133
140
if self ._parse_tag (response , 'bash' ):
134
- return self ._container_handle_bash_command (response , self .check_tool ,
141
+ return self ._container_handle_bash_command (response , self .bash_tool ,
135
142
prompt )
136
143
return None
137
144
@@ -152,7 +159,7 @@ def execute(self, result_history: list[Result]) -> AnalysisResult:
152
159
generated_target_name = os .path .basename (benchmark .target_path )
153
160
sample_id = os .path .splitext (generated_target_name )[0 ]
154
161
generated_oss_fuzz_project = (
155
- f'{ benchmark .id } -{ sample_id } -lldb -{ self .trial :02d} ' )
162
+ f'{ benchmark .id } -{ sample_id } -gdb -{ self .trial :02d} ' )
156
163
generated_oss_fuzz_project = oss_fuzz_checkout .rectify_docker_tag (
157
164
generated_oss_fuzz_project )
158
165
@@ -169,25 +176,35 @@ def execute(self, result_history: list[Result]) -> AnalysisResult:
169
176
else :
170
177
build_script_path = ''
171
178
172
- evaluator_lib .Evaluator .create_ossfuzz_project_with_lldb (
179
+ evaluator_lib .Evaluator .create_ossfuzz_project_with_gdb (
173
180
benchmark , generated_oss_fuzz_project , fuzz_target_path , last_result ,
174
181
build_script_path , last_result .artifact_path )
175
182
176
- self .analyze_tool = LLDBTool (benchmark ,
177
- result = last_result ,
178
- name = 'lldb' ,
179
- project_name = generated_oss_fuzz_project )
180
- self .analyze_tool .execute ('compile > /dev/null' )
181
- # Launch LLDB and load fuzz target binary
182
- self .analyze_tool .execute (f'screen -dmS lldb_session -L '
183
- f'-Logfile /tmp/lldb_log.txt '
184
- f'lldb /out/{ last_result .benchmark .target_name } ' )
185
- self .check_tool = ProjectContainerTool (
183
+ self .gdb_tool = GDBTool (benchmark ,
184
+ result = last_result ,
185
+ name = 'gdb' ,
186
+ project_name = generated_oss_fuzz_project )
187
+ #TODO(dongge): Use a dedicated debugger image, which has the binary and
188
+ #source code.
189
+ self .gdb_tool .execute (
190
+ 'apt update && '
191
+ 'apt install -y software-properties-common && '
192
+ 'add-apt-repository -y ppa:ubuntu-toolchain-r/test && '
193
+ 'apt update && '
194
+ 'apt install -y gdb screen' )
195
+ self .gdb_tool .execute ('export CFLAGS="$CFLAGS -g -O0"' )
196
+ self .gdb_tool .execute ('export CXXFLAGS="$CXXFLAGS -g -O0"' )
197
+ self .gdb_tool .execute ('compile > /dev/null' )
198
+ # Launch GDB and load fuzz target binary
199
+ self .gdb_tool .execute (f'screen -dmS gdb_session -L '
200
+ f'-Logfile /tmp/gdb_log.txt '
201
+ f'gdb /out/{ last_result .benchmark .target_name } ' )
202
+ self .bash_tool = ProjectContainerTool (
186
203
benchmark , name = 'check' , project_name = generated_oss_fuzz_project )
187
- self .check_tool .compile (extra_commands = ' && rm -rf /out/* > /dev/null' )
204
+ self .bash_tool .compile (extra_commands = ' && rm -rf /out/* > /dev/null' )
188
205
prompt = self ._initial_prompt (result_history )
189
- prompt .add_problem (self .analyze_tool .tutorial ())
190
- prompt .add_problem (self .check_tool .tutorial ())
206
+ prompt .add_problem (self .gdb_tool .tutorial ())
207
+ prompt .add_problem (self .bash_tool .tutorial ())
191
208
crash_result = CrashResult (benchmark = benchmark ,
192
209
trial = last_result .trial ,
193
210
work_dirs = last_result .work_dirs ,
@@ -208,9 +225,9 @@ def execute(self, result_history: list[Result]) -> AnalysisResult:
208
225
finally :
209
226
# Cleanup: stop the container
210
227
logger .debug ('Stopping the crash analyze container %s' ,
211
- self .analyze_tool .container_id ,
228
+ self .gdb_tool .container_id ,
212
229
trial = self .trial )
213
- self .analyze_tool .terminate ()
230
+ self .gdb_tool .terminate ()
214
231
215
232
analysis_result = AnalysisResult (
216
233
author = self ,
0 commit comments