Skip to content

Commit

Permalink
Fixed win32 checkpoint resume SEGFAULT
Browse files Browse the repository at this point in the history
  • Loading branch information
qstokkink committed Jan 24, 2025
1 parent b291c08 commit 4c7e23d
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/tribler/core/libtorrent/download_manager/download_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -732,9 +732,16 @@ async def start_handle(self, download: Download, atp: dict) -> None:
resume_data = atp.get("resume_data")
if resume_data:
atp_resume_data_skipped["resume_data"] = "<skipped in log>"
logger.info("Start handle. Download: %s. Atp: %s", str(download), str(atp_resume_data_skipped))
if resume_data:
try:
resume_data_dict = cast(dict[bytes, Any], lt.bdecode(resume_data))
# If the save_path is None or "" win32 SEGFAULTS, see https://github.com/Tribler/tribler/issues/8353
if not resume_data_dict.get(b"save_path"):
resume_data_dict[b"save_path"] = atp.get("save_path", ".").encode()
atp["resume_data"] = lt.bencode(resume_data_dict)
except RuntimeError:
atp.pop("resume_data")
logger.debug("Download resume data: %s", str(atp["resume_data"]))
logger.info("Start handle. Download: %s. Atp: %s", str(download), str(atp_resume_data_skipped))

ltsession = await self.get_session(download.config.get_hops())
infohash = download.get_def().get_infohash()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock, Mock, call, patch

import libtorrent
from configobj import ConfigObj
from configobj.validate import Validator, VdtParamError
from ipv8.test.base import TestBase
Expand Down Expand Up @@ -186,6 +187,28 @@ async def test_start_handle_wait_for_dht(self) -> None:

self.assertTrue(task.done())

async def test_start_handle_empty_save_path(self) -> None:
"""
Test if the "save_path" is always set in the resume_data, otherwise we SEGFAULT on win32!
"""
download = Download(TorrentDef.load_from_memory(TORRENT_WITH_DIRS_CONTENT), None,
checkpoint_disabled=True, config=self.create_mock_download_config())
download.handle = Mock(is_valid=Mock(return_value=True))
self.manager.get_session = AsyncMock(return_value=Mock(get_torrents=Mock(return_value=[])))
self.manager._async_add_torrent = AsyncMock() # noqa: SLF001

await self.manager.start_handle(download, {
"save_path": "/test_path/",
"resume_data": libtorrent.bencode({b"file-format": b"libtorrent resume file", b"file-version": 1})
}) # Schedule async_add_torrent
await sleep(0) # Run async_add_torrent

session, infohash, atp = self.manager._async_add_torrent.call_args[0] # noqa: SLF001

self.assertIn("resume_data", atp)
self.assertIn(b"save_path", libtorrent.bdecode(atp["resume_data"]))
self.assertEqual(b"/test_path/", libtorrent.bdecode(atp["resume_data"])[b"save_path"])

async def test_start_download_existing_handle(self) -> None:
"""
Test if torrents can be added when there is a pre-existing handle.
Expand Down

0 comments on commit 4c7e23d

Please sign in to comment.