Skip to content

Commit 0492895

Browse files
authored
Fix Logging and Error Handling for get_benchmark_final_target_code (#910)
## Description This PR addresses the issue of missing source code by adding enhanced logging and improving error handling in the `get_benchmark_final_target_code()` method. Previously, silent failures could occur, making it difficult to diagnose the root cause of missing source code. ## Changes - **Enhanced Logging**: Logs are added to track when the `sample_id` is invalid or the source code is missing. - **Error Handling**: Ensures that malformed or empty `sample_id` values are handled gracefully and logged appropriately. - **Return Null for Missing Source Code**: In case of an error, the function explicitly returns `None` rather than an empty string for clarity in JSON outputs. #908 It may also refer to #625 ## Benefits - Improved **debuggability** by making it easier to identify the reasons behind missing source code. - Increased **robustness** by preventing silent failures and ensuring more informative logs and error handling.
1 parent 78e7752 commit 0492895

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

report/common.py

+28-2
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,32 @@ def getsize(self) -> int:
256256
class Results:
257257
"""Results provides functions to explore the experiment results in a
258258
particular directory."""
259+
260+
def get_benchmark_final_target_code(self, sample_id: str) -> Optional[str]:
261+
"""Retrieve source code for a sample_id (format: 'benchmark/sample').
262+
263+
Args:
264+
sample_id: A string in the format 'benchmark/sample'.
265+
266+
Returns:
267+
The source code as a string, or None if the source code is missing or the sample_id is invalid.
268+
"""
269+
try:
270+
# Split the sample_id into benchmark and sample
271+
benchmark, sample = sample_id.split('/')
272+
except ValueError:
273+
# Log an error if the sample_id format is invalid
274+
logging.error(f"Invalid sample_id format: '{sample_id}'. Expected 'benchmark/sample'.")
275+
return None
276+
277+
# Retrieve the source code using the existing method
278+
code = self.get_final_target_code(benchmark, sample)
279+
if not code:
280+
# Log a warning if the source code is missing
281+
logging.warning(f"Missing source code for {sample_id}")
282+
return None
283+
284+
return code
259285

260286
def __init__(self, results_dir='results', benchmark_set='all'):
261287
self._results_dir = results_dir
@@ -284,7 +310,7 @@ def get_final_target_code(self, benchmark: str, sample: str) -> str:
284310
targets_dir = os.path.join(self._results_dir, benchmark, 'fixed_targets')
285311
# TODO(donggeliu): Make this consistent with agent output.
286312
if not os.path.exists(targets_dir):
287-
return ''
313+
return None
288314

289315
for name in sorted(FileSystem(targets_dir).listdir()):
290316
path = os.path.join(targets_dir, name)
@@ -293,7 +319,7 @@ def get_final_target_code(self, benchmark: str, sample: str) -> str:
293319
code = f.read()
294320
code = json.dumps(code)
295321
return code
296-
return ''
322+
return None
297323

298324
def get_logs(self, benchmark: str, sample: str) -> list[LogPart]:
299325
status_dir = os.path.join(self._results_dir, benchmark, 'status')

report/templates/crash.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"target_binary": "{{ sample.target_binary }}",
1818
"reproducer": "{{ sample.reproducer }}",
1919
"run_log": "{{ sample.run_log }}",
20-
"source_code": {{ get_benchmark_final_target_code(sample.id) | replace('\\n', '\\\\n')}},
20+
"source_code": {{ get_benchmark_final_target_code(sample.id) | tojson }},
2121
"model": "{{ model }}"
2222
}{% if not loop.last %},{% endif %}
2323
{% endfor %}

report/web.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,13 @@ def _write_benchmark_index(self, benchmark: Benchmark, samples: List[Sample],
218218
def _write_benchmark_crash(self, benchmark: Benchmark, samples: List[Sample]):
219219
"""Generate the benchmark crash.json and write to filesystem."""
220220
try:
221-
rendered = self._jinja.render('crash.json',
222-
benchmark=benchmark.signature,
223-
samples=samples,
224-
get_benchmark_final_target_code=partial(
225-
self._results.get_final_target_code,
226-
benchmark.id))
221+
rendered = self._jinja.render(
222+
'crash.json',
223+
benchmark=benchmark.signature,
224+
samples=samples,
225+
# Changed line below to use new error-handling method
226+
get_benchmark_final_target_code=self._results.get_benchmark_final_target_code
227+
)
227228
self._write(f'benchmark/{benchmark.id}/crash.json', rendered)
228229
except Exception as e:
229230
logging.error('Failed to write benchmark/%s/crash.json:\n%s',
@@ -328,4 +329,4 @@ def main():
328329

329330
if __name__ == '__main__':
330331
logging.getLogger().setLevel(os.environ.get('LOGLEVEL', 'WARN').upper())
331-
main()
332+
main()

0 commit comments

Comments
 (0)