From e0ae227d0af39ee1c55d167d5091889f821ce124 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 31 Oct 2023 10:50:39 -0400 Subject: SL-20546: Add viewer channel and full version to GitHub release page. (cherry picked from commit f71662225eadf1589f5331e763e02e0bb1b72137) --- .github/workflows/build.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1dd2c1d5df..9d04fbe87a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -360,6 +360,11 @@ jobs: # name the release page for the build number so we can find it # easily (analogous to looking up a codeticket build page) name: "v${{ github.run_id }}" + # SL-20546: want the channel and version to be visible on the + # release page + body: | + ${{ needs.build.outputs.viewer_channel }} + ${{ needs.build.outputs.viewer_version }} prerelease: true generate_release_notes: true # the only reason we generate a GH release is to post build products -- cgit v1.2.3 From cac7023996d691f00101429830a23b2cef3a2f83 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 14 Nov 2023 04:09:56 -0500 Subject: SL-20546: Append generated release notes body to our explicit body. For a tag build that generates a release page, try to deduce the git branch to which the tag we're building corresponds and add that to release notes. (cherry picked from commit 9e99bb04a32f2ecc0f0b99686ce5a7adb356596d) --- .github/workflows/build.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9d04fbe87a..c0bec11275 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,6 +24,7 @@ jobs: outputs: viewer_channel: ${{ steps.build.outputs.viewer_channel }} viewer_version: ${{ steps.build.outputs.viewer_version }} + viewer_branch: ${{ steps.build.outputs.viewer_branch }} imagename: ${{ steps.build.outputs.imagename }} env: AUTOBUILD_ADDRSIZE: 64 @@ -176,9 +177,17 @@ jobs: if [[ "$GITHUB_REF_TYPE" == "tag" && "${GITHUB_REF_NAME:0:12}" == "Second_Life_" ]] then viewer_channel="${GITHUB_REF_NAME%#*}" export viewer_channel="${viewer_channel//_/ }" + # Since GITHUB_REF_NAME is a tag rather than a branch, we need + # to discover to what branch this tag corresponds. Get the tip + # commit (for the tag) and then ask for branches containing it. + # Assume GitHub cloned only this tag and its containing branch. + viewer_branch="$(git branch --contains "$(git log -n 1 --format=%h)" | + grep -v '(HEAD')" else export viewer_channel="Second Life Test" + viewer_branch="${GITHUB_REF_NAME}" fi echo "viewer_channel=$viewer_channel" >> "$GITHUB_OUTPUT" + echo "viewer_branch=$viewer_branch" >> "$GITHUB_OUTPUT" # On windows we need to point the build to the correct python # as neither CMake's FindPython nor our custom Python.cmake module @@ -365,8 +374,10 @@ jobs: body: | ${{ needs.build.outputs.viewer_channel }} ${{ needs.build.outputs.viewer_version }} + ${{ needs.build.outputs.viewer_branch }} prerelease: true generate_release_notes: true + append_body: true # the only reason we generate a GH release is to post build products fail_on_unmatched_files: true files: | -- cgit v1.2.3 From a13e70aeffb87e2934f1b01f85dc2c78ea10e20c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 14 Nov 2023 14:20:51 -0500 Subject: SL-20546: Try harder to infer the branch corresponding to build tag. (cherry picked from commit 59eeaed1187e7592fd83380045916f2d8b9d58e7) --- .github/workflows/build.yaml | 8 ++-- .github/workflows/which_branch.py | 77 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/which_branch.py diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c0bec11275..6c40c173db 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -178,11 +178,9 @@ jobs: then viewer_channel="${GITHUB_REF_NAME%#*}" export viewer_channel="${viewer_channel//_/ }" # Since GITHUB_REF_NAME is a tag rather than a branch, we need - # to discover to what branch this tag corresponds. Get the tip - # commit (for the tag) and then ask for branches containing it. - # Assume GitHub cloned only this tag and its containing branch. - viewer_branch="$(git branch --contains "$(git log -n 1 --format=%h)" | - grep -v '(HEAD')" + # to discover to what branch this tag corresponds. + viewer_branch="$(python3 .github/workflows/which_branch.py \ + --token "${{ github.token }}" ${{ github.workflow_sha }})" else export viewer_channel="Second Life Test" viewer_branch="${GITHUB_REF_NAME}" fi diff --git a/.github/workflows/which_branch.py b/.github/workflows/which_branch.py new file mode 100644 index 0000000000..802ea44b5a --- /dev/null +++ b/.github/workflows/which_branch.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +"""\ +@file which_branch.py +@author Nat Goodspeed +@date 2023-11-14 +@brief Discover which git branch(es) correspond to a given commit hash. + +$LicenseInfo:firstyear=2023&license=viewerlgpl$ +Copyright (c) 2023, Linden Research, Inc. +$/LicenseInfo$ +""" + +import github +import re +import sys +import subprocess + +class Error(Exception): + pass + +def branches_for(token, commit, repo=None): + """ + Use the GitHub REST API to discover which branch(es) correspond to the + passed commit hash. The commit string can actually be any of the ways git + permits to identify a commit: + + https://git-scm.com/docs/gitrevisions#_specifying_revisions + + branches_for() generates a (possibly empty) sequence of all the branches + of the specified repo for which the specified commit is the tip. + + If repo is omitted or None, assume the current directory is a local clone + whose 'origin' remote is the GitHub repository of interest. + """ + if not repo: + url = subprocess.check_output(['git', 'remote', 'get-url', 'origin'], + text=True) + parts = re.split(r'[:/]', url.rstrip()) + repo = '/'.join(parts[-2:]).removesuffix('.git') + + gh = github.MainClass.Github(token) + grepo = gh.get_repo(repo) + for branch in grepo.get_branches(): + try: + delta = grepo.compare(base=commit, head=branch.name) + except github.GithubException: + continue + + if delta.ahead_by == 0 and delta.behind_by == 0: + yield branch + +def main(*raw_args): + from argparse import ArgumentParser + parser = ArgumentParser(description= +"%(prog)s reports the branch(es) for which the specified commit hash is the tip.", + epilog="""\ +When GitHub Actions launches a tag build, it checks out the specific changeset +identified by the tag, and so 'git branch' reports detached HEAD. But we use +tag builds to build a GitHub 'release' of the tip of a particular branch, and +it's useful to be able to identify which branch that is. +""") + parser.add_argument('-t', '--token', required=True, + help="""GitHub REST API access token""") + parser.add_argument('-r', '--repo', + help="""GitHub repository name, in the form OWNER/REPOSITORY""") + parser.add_argument('commit', + help="""commit hash at the tip of the sought branch""") + + args = parser.parse_args(raw_args) + for branch in branches_for(token=args.token, commit=args.commit, repo=args.repo): + print(branch.name) + +if __name__ == "__main__": + try: + sys.exit(main(*sys.argv[1:])) + except Error as err: + sys.exit(str(err)) -- cgit v1.2.3 From e4865db0cae7dc3b4e37543cb7cd57d357048340 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 14 Nov 2023 14:30:44 -0500 Subject: SL-20546: Add PyGithub to installed Python packages. (cherry picked from commit 6654ad14eed674e894d2903e0f2ea37c4e806c0f) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6c40c173db..6704737409 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -81,7 +81,7 @@ jobs: path: .master-message-template - name: Install autobuild and python dependencies - run: pip3 install autobuild llsd + run: pip3 install autobuild PyGithub llsd - name: Cache autobuild packages uses: actions/cache@v3 -- cgit v1.2.3 From cfbef4e4f961cafaa004089e2055ff13de35b8dc Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 15 Nov 2023 09:44:38 -0500 Subject: SL-20546: Make dependency on build job explicit, not indirect. The release job has been dependent on sign-and-package-windows and sign-and-package-mac, each of which depends on build. But that indirect dependency doesn't convey access to ${{ needs.build.outputs.xxx }}. Add the build job to direct dependencies so release can access its outputs. (cherry picked from commit 819604d2cee6d4527cc436bebfacddf8642635ff) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6704737409..861f1567c6 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -331,7 +331,7 @@ jobs: version: ${{ needs.build.outputs.viewer_version }} release: - needs: [sign-and-package-windows, sign-and-package-mac] + needs: [build, sign-and-package-windows, sign-and-package-mac] runs-on: ubuntu-latest if: github.ref_type == 'tag' && startsWith(github.ref_name, 'Second_Life_') steps: -- cgit v1.2.3 From 8590ce0533a4bc273b6c0094250fe31fc8e78f1f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 18 Dec 2023 10:59:03 -0500 Subject: DRTVWR-601: Make autobuild set vcs_url, vcs_branch, vcs_revision in viewer's autobuild-package.xml. Ensure that AUTOBUILD_VCS_BRANCH is set before the build. (cherry picked from commit b782ab73e640e434e4ed67fa8dfc951f09757585) (cherry picked from commit 6e8d4f48466a5bbad2fcc27bc2877a30e575d4ce) --- .github/workflows/build.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 861f1567c6..f127ac3f0f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -34,6 +34,9 @@ jobs: AUTOBUILD_GITHUB_TOKEN: ${{ secrets.SHARED_AUTOBUILD_GITHUB_TOKEN }} AUTOBUILD_INSTALLABLE_CACHE: ${{ github.workspace }}/.autobuild-installables AUTOBUILD_VARIABLES_FILE: ${{ github.workspace }}/.build-variables/variables + # Direct autobuild to store vcs_url, vcs_branch and vcs_revision in + # autobuild-package.xml. + AUTOBUILD_VCS_INFO: "true" AUTOBUILD_VSVER: "170" DEVELOPER_DIR: ${{ matrix.developer_dir }} # Ensure that Linden viewer builds engage Bugsplat. @@ -199,6 +202,11 @@ jobs: fi export PYTHON_COMMAND_NATIVE="$(native_path "$PYTHON_COMMAND")" + # branch will be something like "origin/mybranch" + branch="$(git branch -r --contains ${{ github.event.pull_request.head.sha || github.sha }} | head -n 1)" + # strip off "origin/" + export AUTOBUILD_VCS_BRANCH="${branch#*/}" + ./build.sh # Each artifact is downloaded as a distinct .zip file. Multiple jobs -- cgit v1.2.3 From 9b3d4325d9f049bc7315e3772eee2fb5e4bfc83a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 18 Dec 2023 17:35:23 -0500 Subject: DRTVWR-601: Use viewer-build-util/which-branch to determine branch. (cherry picked from commit 2c5066f1fcc0c9f145698ef3aaec72d27bce7181) (cherry picked from commit ff1741cecae0fac6d94507fa4a6e4662219af707) --- .github/workflows/build.yaml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f127ac3f0f..f172883ae6 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -100,10 +100,17 @@ jobs: if: runner.os == 'Windows' run: choco install nsis-unicode + - name: Determine source branch + id: which-branch + uses: secondlife/viewer-build-util/which-branch@v1 + with: + token: ${{ github.token }} + - name: Build id: build shell: bash env: + AUTOBUILD_VCS_BRANCH: ${{ steps.which-branch.outputs.branch }} RUNNER_OS: ${{ runner.os }} run: | # set up things the viewer's build.sh script expects @@ -154,7 +161,7 @@ jobs: } repo_branch() { - git -C "$1" branch | grep '^* ' | cut -c 3- + echo "$AUTOBUILD_VCS_BRANCH" } record_dependencies_graph() { @@ -202,11 +209,6 @@ jobs: fi export PYTHON_COMMAND_NATIVE="$(native_path "$PYTHON_COMMAND")" - # branch will be something like "origin/mybranch" - branch="$(git branch -r --contains ${{ github.event.pull_request.head.sha || github.sha }} | head -n 1)" - # strip off "origin/" - export AUTOBUILD_VCS_BRANCH="${branch#*/}" - ./build.sh # Each artifact is downloaded as a distinct .zip file. Multiple jobs -- cgit v1.2.3 From 8f68199ccd4beeee827ff360e2f36871cedacdfe Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 18 Jan 2024 13:34:40 -0500 Subject: SL-20546: Use branch for autobuild package as well as release page. which_branch.py has moved to viewer-build-util as a reusable action. (cherry picked from commit 09f66828ba573515c3766cce32f4746b8189efcf) --- .github/workflows/build.yaml | 8 +--- .github/workflows/which_branch.py | 77 --------------------------------------- 2 files changed, 1 insertion(+), 84 deletions(-) delete mode 100644 .github/workflows/which_branch.py diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f172883ae6..b323290f6b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,7 +24,7 @@ jobs: outputs: viewer_channel: ${{ steps.build.outputs.viewer_channel }} viewer_version: ${{ steps.build.outputs.viewer_version }} - viewer_branch: ${{ steps.build.outputs.viewer_branch }} + viewer_branch: ${{ steps.which-branch.outputs.branch }} imagename: ${{ steps.build.outputs.imagename }} env: AUTOBUILD_ADDRSIZE: 64 @@ -187,15 +187,9 @@ jobs: if [[ "$GITHUB_REF_TYPE" == "tag" && "${GITHUB_REF_NAME:0:12}" == "Second_Life_" ]] then viewer_channel="${GITHUB_REF_NAME%#*}" export viewer_channel="${viewer_channel//_/ }" - # Since GITHUB_REF_NAME is a tag rather than a branch, we need - # to discover to what branch this tag corresponds. - viewer_branch="$(python3 .github/workflows/which_branch.py \ - --token "${{ github.token }}" ${{ github.workflow_sha }})" else export viewer_channel="Second Life Test" - viewer_branch="${GITHUB_REF_NAME}" fi echo "viewer_channel=$viewer_channel" >> "$GITHUB_OUTPUT" - echo "viewer_branch=$viewer_branch" >> "$GITHUB_OUTPUT" # On windows we need to point the build to the correct python # as neither CMake's FindPython nor our custom Python.cmake module diff --git a/.github/workflows/which_branch.py b/.github/workflows/which_branch.py deleted file mode 100644 index 802ea44b5a..0000000000 --- a/.github/workflows/which_branch.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python3 -"""\ -@file which_branch.py -@author Nat Goodspeed -@date 2023-11-14 -@brief Discover which git branch(es) correspond to a given commit hash. - -$LicenseInfo:firstyear=2023&license=viewerlgpl$ -Copyright (c) 2023, Linden Research, Inc. -$/LicenseInfo$ -""" - -import github -import re -import sys -import subprocess - -class Error(Exception): - pass - -def branches_for(token, commit, repo=None): - """ - Use the GitHub REST API to discover which branch(es) correspond to the - passed commit hash. The commit string can actually be any of the ways git - permits to identify a commit: - - https://git-scm.com/docs/gitrevisions#_specifying_revisions - - branches_for() generates a (possibly empty) sequence of all the branches - of the specified repo for which the specified commit is the tip. - - If repo is omitted or None, assume the current directory is a local clone - whose 'origin' remote is the GitHub repository of interest. - """ - if not repo: - url = subprocess.check_output(['git', 'remote', 'get-url', 'origin'], - text=True) - parts = re.split(r'[:/]', url.rstrip()) - repo = '/'.join(parts[-2:]).removesuffix('.git') - - gh = github.MainClass.Github(token) - grepo = gh.get_repo(repo) - for branch in grepo.get_branches(): - try: - delta = grepo.compare(base=commit, head=branch.name) - except github.GithubException: - continue - - if delta.ahead_by == 0 and delta.behind_by == 0: - yield branch - -def main(*raw_args): - from argparse import ArgumentParser - parser = ArgumentParser(description= -"%(prog)s reports the branch(es) for which the specified commit hash is the tip.", - epilog="""\ -When GitHub Actions launches a tag build, it checks out the specific changeset -identified by the tag, and so 'git branch' reports detached HEAD. But we use -tag builds to build a GitHub 'release' of the tip of a particular branch, and -it's useful to be able to identify which branch that is. -""") - parser.add_argument('-t', '--token', required=True, - help="""GitHub REST API access token""") - parser.add_argument('-r', '--repo', - help="""GitHub repository name, in the form OWNER/REPOSITORY""") - parser.add_argument('commit', - help="""commit hash at the tip of the sought branch""") - - args = parser.parse_args(raw_args) - for branch in branches_for(token=args.token, commit=args.commit, repo=args.repo): - print(branch.name) - -if __name__ == "__main__": - try: - sys.exit(main(*sys.argv[1:])) - except Error as err: - sys.exit(str(err)) -- cgit v1.2.3 From a8cd70123b075440c6343862349495421d12be45 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 18 Jan 2024 13:43:34 -0500 Subject: SL-20546: PyGithub was only needed for local which_branch.py. Now that which_branch.py has moved to viewer-build-util, so has the PyGithub dependency. (cherry picked from commit dd0ec112fe5ded8ed5f69b72b3df26343ca12d35) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b323290f6b..0cd5595e4b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -84,7 +84,7 @@ jobs: path: .master-message-template - name: Install autobuild and python dependencies - run: pip3 install autobuild PyGithub llsd + run: pip3 install autobuild llsd - name: Cache autobuild packages uses: actions/cache@v3 -- cgit v1.2.3 From 9f326f5b960b0d039280e4c04e7eb44fc094e40e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 15 Feb 2024 11:21:31 -0500 Subject: Engage new viewer-build-util/which-branch with relnotes output. Put whatever release notes we retrieve into the generated release page. (cherry picked from commit ff543b744ee0b0fd4dd90b46419ae50a570572ab) --- .github/workflows/build.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0cd5595e4b..4d3dd31801 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -25,6 +25,7 @@ jobs: viewer_channel: ${{ steps.build.outputs.viewer_channel }} viewer_version: ${{ steps.build.outputs.viewer_version }} viewer_branch: ${{ steps.which-branch.outputs.branch }} + relnotes: ${{ steps.which-branch.outputs.relnotes }} imagename: ${{ steps.build.outputs.imagename }} env: AUTOBUILD_ADDRSIZE: 64 @@ -102,7 +103,7 @@ jobs: - name: Determine source branch id: which-branch - uses: secondlife/viewer-build-util/which-branch@v1 + uses: secondlife/viewer-build-util/which-branch@relnotes with: token: ${{ github.token }} @@ -377,6 +378,7 @@ jobs: ${{ needs.build.outputs.viewer_channel }} ${{ needs.build.outputs.viewer_version }} ${{ needs.build.outputs.viewer_branch }} + ${{ needs.build.outputs.relnotes }} prerelease: true generate_release_notes: true append_body: true -- cgit v1.2.3 From 603d3a865a0f619488555dd2d205e0eff4280cc5 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Feb 2024 11:23:47 -0500 Subject: Try to generate release notes for this specific branch. Also try to cross-reference release page and build page. (cherry picked from commit a908b4cfa98716d4a838fc1e5a6789faa15d16cf) --- .github/workflows/build.yaml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4d3dd31801..6713e429cc 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -367,25 +367,30 @@ jobs: mv newview/viewer_version.txt macOS-viewer_version.txt # forked from softprops/action-gh-release - - uses: secondlife-3p/action-gh-release@v1 + - name: Create GitHub release + id: release + uses: secondlife-3p/action-gh-release@v1 with: - # name the release page for the build number so we can find it - # easily (analogous to looking up a codeticket build page) - name: "v${{ github.run_id }}" + # name the release page for the branch + name: "${{ needs.build.outputs.viewer_branch }}" # SL-20546: want the channel and version to be visible on the # release page body: | + Build ${{ github.repositoryUrl }}/actions/runs/${{ github.run_id }} ${{ needs.build.outputs.viewer_channel }} ${{ needs.build.outputs.viewer_version }} - ${{ needs.build.outputs.viewer_branch }} ${{ needs.build.outputs.relnotes }} prerelease: true generate_release_notes: true + target_commitish: ${{ github.ref }} append_body: true - # the only reason we generate a GH release is to post build products fail_on_unmatched_files: true files: | *.dmg *.exe *-autobuild-package.xml *-viewer_version.txt + + - name: post release URL + run: | + echo "::notice::Release ${{ steps.release.outputs.url }}" -- cgit v1.2.3 From d7e6a7dbd057e03984583f4524953f8ae5250f17 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Feb 2024 12:20:31 -0500 Subject: Try basing the GH release on github.ref_name instead of github.ref. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using github.ref as action-gh-release's target_commitish produces: ⚠️ GitHub release failed with status: 422 [{"resource":"Release","code":"invalid","field":"target_commitish"}] (cherry picked from commit c6a6db8488a8b3e7ea6534fbf5e2fe2b17864421) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 6713e429cc..b156133799 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -382,7 +382,7 @@ jobs: ${{ needs.build.outputs.relnotes }} prerelease: true generate_release_notes: true - target_commitish: ${{ github.ref }} + target_commitish: ${{ github.ref_name }} append_body: true fail_on_unmatched_files: true files: | -- cgit v1.2.3 From 7c52db381c61f10aa5e4e9c5414c54c0e49d5815 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Feb 2024 13:26:29 -0500 Subject: Try basing release notes on github.sha rather than github.ref_name. (cherry picked from commit 4edd78f2e54b3cd2e0b0a4b9300dfc669231dd98) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b156133799..1816e8b48f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -382,7 +382,7 @@ jobs: ${{ needs.build.outputs.relnotes }} prerelease: true generate_release_notes: true - target_commitish: ${{ github.ref_name }} + target_commitish: ${{ github.sha }} append_body: true fail_on_unmatched_files: true files: | -- cgit v1.2.3 From 7ad13c851198d3ea2692c0c16f2eb844ebca8bf5 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Feb 2024 15:51:31 -0500 Subject: Leverage action-gh-release's new previous_tag input. This should (!) allow us to generate full release notes relative to the previous viewer release, instead of letting action-gh-release guess incorrectly. Also try again to add to the release page a back-link to the specific build. (cherry picked from commit 88ebb92f05dade00cc8fc519cc062a458ecd48f2) --- .github/workflows/build.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1816e8b48f..f76d4286e2 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -369,20 +369,21 @@ jobs: # forked from softprops/action-gh-release - name: Create GitHub release id: release - uses: secondlife-3p/action-gh-release@v1 + uses: secondlife-3p/action-gh-release@feat/add-generateReleaseNotes with: # name the release page for the branch name: "${{ needs.build.outputs.viewer_branch }}" # SL-20546: want the channel and version to be visible on the # release page body: | - Build ${{ github.repositoryUrl }}/actions/runs/${{ github.run_id }} + Build ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ${{ needs.build.outputs.viewer_channel }} ${{ needs.build.outputs.viewer_version }} ${{ needs.build.outputs.relnotes }} prerelease: true generate_release_notes: true target_commitish: ${{ github.sha }} + previous_tag: 7.1.2-release append_body: true fail_on_unmatched_files: true files: | -- cgit v1.2.3 From 3ee3e011ffe2b0d0810f61b5d35afb24ee4095a0 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 26 Feb 2024 17:05:56 -0500 Subject: Base generated release notes on new floating tag 'release' instead of on the current tag 7.1.2-release. (cherry picked from commit 27b298d8bc720ff315c8e74cc5bff9ff9ead0552) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f76d4286e2..b3dafd43c9 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -383,7 +383,7 @@ jobs: prerelease: true generate_release_notes: true target_commitish: ${{ github.sha }} - previous_tag: 7.1.2-release + previous_tag: release append_body: true fail_on_unmatched_files: true files: | -- cgit v1.2.3 From 00d7fef75ed860596ab87904209a827fd9de867e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 28 Feb 2024 08:45:12 -0500 Subject: Reference updated action-gh-release@v1 instead of the branch that got pulled. (cherry picked from commit b42e01d7acf5d4c55612c3a7df0e1ff6ee5ed951) --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index b3dafd43c9..8b08bb3960 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -369,7 +369,7 @@ jobs: # forked from softprops/action-gh-release - name: Create GitHub release id: release - uses: secondlife-3p/action-gh-release@feat/add-generateReleaseNotes + uses: secondlife-3p/action-gh-release@v1 with: # name the release page for the branch name: "${{ needs.build.outputs.viewer_branch }}" -- cgit v1.2.3 From 9b8800f216fb0a6efa80b76ca15d0491bd9948ee Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 1 Mar 2024 16:43:15 -0500 Subject: Now that viewer-build-util@relnotes has merged to v1, use @v1. --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8b08bb3960..df49f5fa42 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -103,7 +103,7 @@ jobs: - name: Determine source branch id: which-branch - uses: secondlife/viewer-build-util/which-branch@relnotes + uses: secondlife/viewer-build-util/which-branch@v1 with: token: ${{ github.token }} -- cgit v1.2.3 From 78ce375dda587cbc86ade15a4d564a469e6db9d3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 3 Jan 2024 22:57:28 +0200 Subject: SL-17896 Don't crash silently if files are missing or out of memory Under debug LL_ERRS will show a message as well, but release won't show anything and will quit silently so show a notification when applicable. --- indra/llcommon/llcoros.cpp | 1 + indra/llcommon/llerror.cpp | 42 ++++++++++++++++++++++ indra/llcommon/llerror.h | 23 ++++++++++++ indra/llcommon/llexception.cpp | 1 + indra/llcorehttp/_httpservice.cpp | 1 + indra/llimage/llimagebmp.cpp | 1 + indra/llimage/llimagedxt.cpp | 1 + indra/llimage/llimagetga.cpp | 1 + indra/llrender/llimagegl.cpp | 3 ++ indra/llui/llnotifications.cpp | 3 ++ indra/llui/lltexteditor.cpp | 1 + indra/llui/lltransutil.cpp | 8 ++++- indra/newview/llappcorehttp.cpp | 1 + indra/newview/llappviewer.cpp | 29 ++++++++++++--- indra/newview/llappviewer.h | 1 + indra/newview/llavatarrenderinfoaccountant.cpp | 2 ++ indra/newview/llmeshrepository.cpp | 8 ++--- indra/newview/llviewermenu.cpp | 16 +++++++++ indra/newview/skins/default/xui/en/menu_viewer.xml | 6 ++++ indra/newview/skins/default/xui/en/strings.xml | 13 ++++++- 20 files changed, 152 insertions(+), 10 deletions(-) diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 3ab97b557f..1d383f174d 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -278,6 +278,7 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl catch (std::bad_alloc&) { // Out of memory on stack allocation? + LLError::LLUserWarningMsg::showOutOfMemory(); printActiveCoroutines(); LL_ERRS("LLCoros") << "Bad memory allocation in LLCoros::launch(" << prefix << ")!" << LL_ENDL; } diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 414515854a..3de641fcba 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1601,6 +1601,48 @@ namespace LLError { return out << boost::stacktrace::stacktrace(); } + + // LLOutOfMemoryWarning + std::string LLUserWarningMsg::sLocalizedOutOfMemoryTitle; + std::string LLUserWarningMsg::sLocalizedOutOfMemoryWarning; + LLUserWarningMsg::Handler LLUserWarningMsg::sHandler; + + void LLUserWarningMsg::show(const std::string& message) + { + if (sHandler) + { + sHandler(std::string(), message); + } + } + + void LLUserWarningMsg::showOutOfMemory() + { + if (sHandler && !sLocalizedOutOfMemoryTitle.empty()) + { + sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning); + } + } + + void LLUserWarningMsg::showMissingFiles() + { + // Files Are missing, likely can't localize. + const std::string error_string = + "Second Life viewer couldn't access some of the files it needs and will be closed." + "\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and " + "contact https://support.secondlife.com if issue persists after reinstall."; + sHandler("Missing Files", error_string); + } + + void LLUserWarningMsg::setHandler(const LLUserWarningMsg::Handler &handler) + { + sHandler = handler; + } + + void LLUserWarningMsg::setOutOfMemoryStrings(const std::string& title, const std::string& message) + { + sLocalizedOutOfMemoryTitle = title; + sLocalizedOutOfMemoryWarning = message; + } } void crashdriver(void (*callback)(int*)) diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 05dd88ee51..6f6b349cf5 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -39,6 +39,7 @@ #include "llpreprocessor.h" #include +#include // std::function const int LL_ERR_NOERR = 0; @@ -301,6 +302,28 @@ namespace LLError { friend std::ostream& operator<<(std::ostream& out, const LLStacktrace&); }; + + // Provides access to OS notification popup on error, since + // not everything has access to OS's messages + class LLUserWarningMsg + { + public: + typedef std::function Handler; + static void setHandler(const Handler&); + static void setOutOfMemoryStrings(const std::string& title, const std::string& message); + + // When viewer encounters bad alloc or can't access files try warning user about reasons + static void showOutOfMemory(); + static void showMissingFiles(); + // Genering error + static void show(const std::string&); + + private: + // needs to be preallocated before viewer runs out of memory + static std::string sLocalizedOutOfMemoryTitle; + static std::string sLocalizedOutOfMemoryWarning; + static Handler sHandler; + }; } //this is cheaper than llcallstacks if no need to output other variables to call stacks. diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index 46560b5e4c..0787bde57f 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -37,6 +37,7 @@ #include "llerror.h" #include "llerrorcontrol.h" + // used to attach and extract stacktrace information to/from boost::exception, // see https://www.boost.org/doc/libs/release/doc/html/stacktrace/getting_started.html#stacktrace.getting_started.exceptions_with_stacktrace // apparently the struct passed as the first template param needs no definition? diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp index 294acd7f63..517076804d 100644 --- a/indra/llcorehttp/_httpservice.cpp +++ b/indra/llcorehttp/_httpservice.cpp @@ -320,6 +320,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread) LLMemory::logMemoryInfo(TRUE); //output possible call stacks to log file. + LLError::LLUserWarningMsg::showOutOfMemory(); LLError::LLCallStacks::print(); LL_ERRS() << "Bad memory allocation in HttpService::threadRun()!" << LL_ENDL; diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp index 90b7272efa..cdea0da68d 100644 --- a/indra/llimage/llimagebmp.cpp +++ b/indra/llimage/llimagebmp.cpp @@ -321,6 +321,7 @@ bool LLImageBMP::updateData() mColorPalette = new(std::nothrow) U8[color_palette_size]; if (!mColorPalette) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Out of memory in LLImageBMP::updateData()" << LL_ENDL; return false; } diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp index 36317a5ba8..ae76c5243f 100644 --- a/indra/llimage/llimagedxt.cpp +++ b/indra/llimage/llimagedxt.cpp @@ -437,6 +437,7 @@ bool LLImageDXT::convertToDXR() U8* newdata = (U8*)ll_aligned_malloc_16(total_bytes); if (!newdata) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Out of memory in LLImageDXT::convertToDXR()" << LL_ENDL; return false; } diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp index 88bdae9b80..152a7f309c 100644 --- a/indra/llimage/llimagetga.cpp +++ b/indra/llimage/llimagetga.cpp @@ -266,6 +266,7 @@ bool LLImageTGA::updateData() mColorMap = new(std::nothrow) U8[ color_map_bytes ]; if (!mColorMap) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Out of Memory in bool LLImageTGA::updateData()" << LL_ENDL; return false; } diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index c6fd824c4e..56a12b07b1 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1353,6 +1353,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt scratch = new(std::nothrow) U32[width * height]; if (!scratch) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) << " bytes for a manual image W" << width << " H" << height << LL_ENDL; } @@ -1378,6 +1379,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt scratch = new(std::nothrow) U32[width * height]; if (!scratch) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) << " bytes for a manual image W" << width << " H" << height << LL_ENDL; } @@ -1406,6 +1408,7 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt scratch = new(std::nothrow) U32[width * height]; if (!scratch) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) << " bytes for a manual image W" << width << " H" << height << LL_ENDL; } diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index d736aa6634..2fe9ee18e3 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1553,6 +1553,7 @@ bool LLNotifications::loadTemplates() if (!success || root.isNull() || !root->hasName( "notifications" )) { + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL; return false; } @@ -1563,6 +1564,7 @@ bool LLNotifications::loadTemplates() if(!params.validateBlock()) { + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); LL_ERRS() << "Problem reading XUI from UI Notifications file: " << base_filename << LL_ENDL; return false; } @@ -1629,6 +1631,7 @@ bool LLNotifications::loadVisibilityRules() if(!params.validateBlock()) { + LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile")); LL_ERRS() << "Problem reading UI Notification Visibility Rules file: " << full_filename << LL_ENDL; return false; } diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 092739a538..a247e8700a 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -2694,6 +2694,7 @@ BOOL LLTextEditor::importBuffer(const char* buffer, S32 length ) char* text = new char[ text_len + 1]; if (text == NULL) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "Memory allocation failure." << LL_ENDL; return FALSE; } diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 5da722a72b..6c486f29ba 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -44,8 +44,13 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::setdumpCurrentDirectories(LLError::LEVEL_WARN); - LL_ERRS() << "Couldn't load string table " << xml_filename << ". Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; + LL_ERRS() << "Couldn't load string table " << xml_filename << " " << errno << LL_ENDL; return false; } @@ -60,6 +65,7 @@ bool LLTransUtil::parseLanguageStrings(const std::string& xml_filename) if (!success) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Couldn't load localization table " << xml_filename << LL_ENDL; return false; } diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp index debf93dccd..51e259992d 100644 --- a/indra/newview/llappcorehttp.cpp +++ b/indra/newview/llappcorehttp.cpp @@ -168,6 +168,7 @@ void LLAppCoreHttp::init() } else { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS("Init") << "Missing CA File; should be at " << ca_file << LL_ENDL; } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e6a47f1c64..a1fecdb981 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -362,7 +362,6 @@ BOOL gRandomizeFramerate = FALSE; BOOL gPeriodicSlowFrame = FALSE; BOOL gCrashOnStartup = FALSE; -BOOL gLLErrorActivated = FALSE; BOOL gLogoutInProgress = FALSE; BOOL gSimulateMemLeak = FALSE; @@ -2253,9 +2252,6 @@ void errorCallback(LLError::ELevel level, const std::string &error_string) OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK); #endif - //Set the ErrorActivated global so we know to create a marker file - gLLErrorActivated = true; - gDebugInfo["FatalMessage"] = error_string; // We're not already crashing -- we simply *intend* to crash. Since we // haven't actually trashed anything yet, we can afford to write the whole @@ -2264,6 +2260,14 @@ void errorCallback(LLError::ELevel level, const std::string &error_string) } } +void errorMSG(const std::string& title_string, const std::string& message_string) +{ + if (!message_string.empty()) + { + OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK); + } +} + void LLAppViewer::initLoggingAndGetLastDuration() { // @@ -2275,6 +2279,8 @@ void LLAppViewer::initLoggingAndGetLastDuration() LLError::addGenericRecorder(&errorCallback); //LLError::setTimeFunction(getRuntime); + LLError::LLUserWarningMsg::setHandler(errorMSG); + if (mSecondInstance) { @@ -2412,6 +2418,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, { // failed to load if(file.required) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Error: Cannot load required settings file from: " << full_settings_path << LL_ENDL; return false; } @@ -2510,6 +2517,7 @@ bool LLAppViewer::initConfiguration() if (!success) { LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL; + LLError::LLUserWarningMsg::showMissingFiles(); if (gDirUtilp->fileExists(settings_file_list)) { LL_ERRS() << "Cannot load default configuration file settings_files.xml. " @@ -2533,6 +2541,7 @@ bool LLAppViewer::initConfiguration() if (!mSettingsLocationList->validateBlock()) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Invalid settings file list " << settings_file_list << LL_ENDL; } @@ -2967,6 +2976,8 @@ bool LLAppViewer::initConfiguration() LLEventPumps::instance().obtain("LLControlGroup").post(LLSDMap("init", key)); } + LLError::LLUserWarningMsg::setOutOfMemoryStrings(LLTrans::getString("MBOutOfMemoryTitle"), LLTrans::getString("MBOutOfMemoryErr")); + return true; // Config was successful. } @@ -3004,6 +3015,7 @@ void LLAppViewer::initStrings() // initial check to make sure files are there failed gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN); + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Viewer failed to find localization and UI files." << " Please reinstall viewer from https://secondlife.com/support/downloads" << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; @@ -4309,6 +4321,7 @@ void LLAppViewer::loadKeyBindings() key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml"); if (!gViewerInput.loadBindingsXML(key_bindings_file)) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL; } } @@ -5399,6 +5412,14 @@ void LLAppViewer::forceErrorLLError() LL_ERRS() << "This is a deliberate llerror" << LL_ENDL; } +void LLAppViewer::forceErrorLLErrorMsg() +{ + LLError::LLUserWarningMsg::show("Deliberate error"); + // Note: under debug this will show a message as well, + // but release won't show anything and will quit silently + LL_ERRS() << "This is a deliberate llerror with a message" << LL_ENDL; +} + void LLAppViewer::forceErrorBreakpoint() { LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 6d1496d517..77a1cdb485 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -152,6 +152,7 @@ public: // LLAppViewer testing helpers. // *NOTE: These will potentially crash the viewer. Only for debugging. virtual void forceErrorLLError(); + virtual void forceErrorLLErrorMsg(); virtual void forceErrorBreakpoint(); virtual void forceErrorBadMemoryAccess(); virtual void forceErrorInfiniteLoop(); diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index a6c9a41fa4..b95b971890 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -339,6 +339,7 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio } catch (std::bad_alloc&) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL; } } @@ -370,6 +371,7 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi } catch (std::bad_alloc&) { + LLError::LLUserWarningMsg::showOutOfMemory(); LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL; } } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 01d6469010..6dc4f25d02 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1360,7 +1360,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL; + LL_WARNS(LOG_MESH) << "Failed to allocate memory for skin info, size: " << size << LL_ENDL; return false; } LLMeshRepository::sCacheBytesRead += size; @@ -1473,7 +1473,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; + LL_WARNS(LOG_MESH) << "Failed to allocate memory for mesh decomposition, size: " << size << LL_ENDL; return false; } LLMeshRepository::sCacheBytesRead += size; @@ -1575,7 +1575,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS_ONCE(LOG_MESH) << "Failed to allocate memory for physics shape, size: " << size << LL_ENDL; + LL_WARNS(LOG_MESH) << "Failed to allocate memory for physics shape, size: " << size << LL_ENDL; return false; } file.read(buffer, size); @@ -1770,7 +1770,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U8* buffer = new(std::nothrow) U8[size]; if (!buffer) { - LL_WARNS_ONCE(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; + LL_WARNS(LOG_MESH) << "Can't allocate memory for mesh " << mesh_id << " LOD " << lod << ", size: " << size << LL_ENDL; // todo: for now it will result in indefinite constant retries, should result in timeout // or in retry-count and disabling mesh. (but usually viewer is beyond saving at this point) return false; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 2cf341f87f..289ad2a948 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -289,6 +289,7 @@ void handle_disconnect_viewer(void *); void force_error_breakpoint(void *); void force_error_llerror(void *); +void force_error_llerror_msg(void*); void force_error_bad_memory_access(void *); void force_error_infinite_loop(void *); void force_error_software_exception(void *); @@ -2400,6 +2401,15 @@ class LLAdvancedForceErrorLlerror : public view_listener_t } }; +class LLAdvancedForceErrorLlerrorMsg: public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + force_error_llerror_msg(NULL); + return true; + } +}; + class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -8379,6 +8389,11 @@ void force_error_llerror(void *) LLAppViewer::instance()->forceErrorLLError(); } +void force_error_llerror_msg(void*) +{ + LLAppViewer::instance()->forceErrorLLErrorMsg(); +} + void force_error_bad_memory_access(void *) { LLAppViewer::instance()->forceErrorBadMemoryAccess(); @@ -9604,6 +9619,7 @@ void initialize_menus() // Advanced > Debugging view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint"); view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror"); + view_listener_t::addMenu(new LLAdvancedForceErrorLlerrorMsg(), "Advanced.ForceErrorLlerrorMsg"); view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess"); view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro"); view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop"); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 38763cd9a8..7b3b4ed395 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2716,6 +2716,12 @@ function="World.EnvPreset" + + + diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index f3b26820d2..7360c06f86 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3019,8 +3019,19 @@ Running in window. If you continue to receive this message, contact the [SUPPORT_SITE]. + Out Of Memory + + [APP_NAME]'s request for memory failed. Application can't proceed and will be closed. - +If your computer's RAM is low, quit any heavy applications before runing Second Life, allocate a page file or reduce graphical settings like draw distance. + + + [APP_NAME] couldn't access or find some of the files it needs and will be closed. + +Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall. + + + 5 O'Clock Shadow All White -- cgit v1.2.3 From 6c43baf0298929ee315bdb3d95f0bd23f589a4cf Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 24 Jan 2024 23:56:22 +0200 Subject: Issue #54 LLRender::init crash --- indra/llrender/llrender.cpp | 10 +++++++++- indra/llrender/llrender.h | 2 +- indra/newview/llviewerwindow.cpp | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index ee66122774..4d64dc9e10 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -857,7 +857,7 @@ LLRender::~LLRender() shutdown(); } -void LLRender::init(bool needs_vertex_buffer) +bool LLRender::init(bool needs_vertex_buffer) { #if LL_WINDOWS if (gGLManager.mHasDebugOutput && gDebugGL) @@ -879,6 +879,13 @@ void LLRender::init(bool needs_vertex_buffer) // necessary for reflection maps glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); +#if LL_WINDOWS + if (glGenVertexArrays == nullptr) + { + return false; + } +#endif + { //bind a dummy vertex array object so we're core profile compliant U32 ret; glGenVertexArrays(1, &ret); @@ -889,6 +896,7 @@ void LLRender::init(bool needs_vertex_buffer) { initVertexBuffer(); } + return true; } void LLRender::initVertexBuffer() diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index fd922affba..716b52354d 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -375,7 +375,7 @@ public: LLRender(); ~LLRender(); - void init(bool needs_vertex_buffer); + bool init(bool needs_vertex_buffer); void initVertexBuffer(); void resetVertexBuffer(); void shutdown(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 47c7eed872..37e64dfc17 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1957,7 +1957,11 @@ LLViewerWindow::LLViewerWindow(const Params& p) // Initialize OpenGL Renderer LLVertexBuffer::initClass(mWindow); LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; - gGL.init(true); + if (!gGL.init(true)) + { + LLError::LLUserWarningMsg::show(LLTrans::getString("MBVideoDrvErr")); + LL_ERRS() << "gGL not initialized" << LL_ENDL; + } if (LLFeatureManager::getInstance()->isSafe() || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) -- cgit v1.2.3