Resolving VSCode Crash After Update on macOS

Recently, I encountered a frustrating issue with Visual Studio Code (VSCode) on my macOS system. After performing an update, the application refused to open, effectively crashing on startup. If you’re facing a similar problem, you’re not alone, and there’s a solution available.

The Issue

The problem appears to be affecting macOS users who recently updated their VSCode installation. Upon attempting to launch the application, it fails to open, leaving users unable to access their development environment.
The problem I experienced is exactly the same as described in this Stack Overflow question:
https://stackoverflow.com/questions/78710474/cannot-open-vscode-on-macos-after-update

The Solution

After some research, I found that this issue has been reported and addressed by the VSCode team. Here’s how you can resolve it:

  1. Download VSCode version 1.90
    The key to fixing this problem is to revert to a previous, stable version of VSCode. Specifically, you’ll need to download and install VSCode version 1.90.

    You can find the download link for VSCode 1.90 on the official Visual Studio Code updates page:
    VSCode 1.90 Download

  2. Install the downloaded version
    Once you’ve downloaded VSCode 1.90, install it on your macOS system. This should replace the problematic updated version.

  3. Launch VSCode
    After installation, try launching VSCode again. It should now open without crashing.

Additional Information

For those interested in the technical details or ongoing discussions about this issue, you can refer to the following GitHub issue threads:

These threads contain valuable information about the nature of the problem and potential long-term fixes that the VSCode team may implement.

Conclusion

While it’s inconvenient to encounter such issues after an update, it’s reassuring to know that the VSCode community and development team are quick to identify and provide solutions. By reverting to version 1.90, you should be able to continue using VSCode without interruption.

Remember to keep an eye on future updates, as the VSCode team will likely address this issue in upcoming releases.

How to Use Git Tag

Git tags are used to mark specific points in your repository’s history. This is typically done to mark release points (e.g., v1.0, v2.0). There are two types of tags in Git: lightweight and annotated. Here’s how to use them:

Creating Tags

  1. Lightweight Tag:
    A lightweight tag is like a branch that doesn’t change. It’s just a pointer to a commit.

    1
    git tag <tagname>

    Example:

    1
    git tag v1.0
  2. Annotated Tag:
    Annotated tags are stored as full objects in the Git database. They can have a message, and metadata such as the tagger’s name, email, and date.

    1
    git tag -a <tagname> -m "message"

    Example:

    1
    git tag -a v1.0 -m "Release version 1.0"

Viewing Tags

To list all tags in your repository:

1
git tag

To view details of a specific tag:

1
git show <tagname>

Example:

1
git show v1.0

Sharing Tags

By default, git push does not push tags to remote repositories. To push a specific tag:

1
git push origin <tagname>

Example:

1
git push origin v1.0

To push all tags at once:

1
git push origin --tags

Deleting Tags

To delete a local tag:

1
git tag -d <tagname>

Example:

1
git tag -d v1.0

To delete a remote tag:

1
git push origin --delete <tagname>

Example:

1
git push origin --delete v1.0

Checking Out Tags

To checkout a specific tag (this puts you in a “detached HEAD” state, meaning you are not on a branch):

1
git checkout <tagname>

Example:

1
git checkout v1.0

Remember that when you are in a detached HEAD state, any changes you make are not associated with any branch unless you create a new branch from this state.

Summary

  • Create a lightweight tag: git tag <tagname>
  • Create an annotated tag: git tag -a <tagname> -m "message"
  • List tags: git tag
  • Show tag details: git show <tagname>
  • Push a specific tag: git push origin <tagname>
  • Push all tags: git push origin --tags
  • Delete a local tag: git tag -d <tagname>
  • Delete a remote tag: git push origin --delete <tagname>
  • Checkout a tag: git checkout <tagname>

Using these commands, you can effectively manage tags in your Git repositories.

Best Practices for Managing Side Effects in React with `useEffect`

When working with useEffect in React, the way you handle subscriptions is crucial for maintaining performance and avoiding memory leaks. Let’s explore two forms of useEffect for managing authentication state changes using Firebase’s onAuthStateChanged and understand why one approach is superior.

Handling Subscriptions with Cleanup

First, consider the following example where we properly manage the subscription by including an unsubscribe mechanism:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
useEffect(() => {
const auth = getAuth();
const unsubscribe = onAuthStateChanged(auth, (user) => {
if (user) {
const userProfile: UserInfo = user.providerData[0];
setUserInfo({
providerId: userProfile.providerId,
uid: userProfile.uid,
displayName: userProfile.displayName,
email: userProfile.email,
photoURL: userProfile.photoURL,
});
}
setLoading(false);
});

return () => unsubscribe();
}, []);

Handling Subscriptions Without Cleanup

Now, compare it with a version that does not manage the subscription cleanup:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
useEffect(() => {
const auth = getAuth();
onAuthStateChanged(auth, (user) => {
if (user) {
const userProfile: UserInfo = user.providerData[0];
setUserInfo({
providerId: userProfile.providerId,
uid: userProfile.uid,
displayName: userProfile.displayName,
email: userProfile.email,
photoURL: userProfile.photoURL,
});
}
setLoading(false);
});
}, []);

Why the Unsubscribe Form is Preferable

Using the form with unsubscribe is generally better for several reasons:

  1. Memory Management:

    • Subscriptions persist until explicitly cancelled. By calling unsubscribe in the cleanup phase of useEffect, you ensure the subscription is terminated when the component unmounts or the effect dependencies change, preventing memory leaks.
  2. Avoiding Multiple Subscriptions:

    • If the dependencies of the useEffect change, the effect re-runs. Without cleanup, each re-run creates a new subscription, leading to multiple active subscriptions and potential issues. The unsubscribe method ensures only one active subscription at a time.
  3. Best Practices:

    • Explicitly handling side effect cleanups is a best practice in React. It ensures your component releases resources correctly, leading to predictable behavior and preventing issues caused by stale listeners or handlers.

Conclusion

While the second form (without unsubscribe) may be adequate for simple scenarios or quick experiments, the first form (with unsubscribe) is more robust. It aligns with React’s best practices for managing side effects and resource cleanup, ensuring your component remains performant and reliable, particularly in larger or more complex applications. Always favor the approach that includes cleanup to maintain optimal performance and avoid potential pitfalls.

retro warning message

1
[W NNPACK.cpp:61] Could not initialize NNPACK! Reason: Unsupported hardware.

https://github.com/pytorch/pytorch/blob/70f4b3551c01230d4ab00da7bf453fa7c6b14eb9/aten/src/ATen/native/NNPACK.cpp#L52-L72

https://discuss.pytorch.org/t/bug-w-nnpack-cpp-80-could-not-initialize-nnpack-reason-unsupported-hardware/107518/23

Environment Architecture CPU requirements
Linux x86-64 AVX2 and 3-level cache hierarchy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 36 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Vendor ID: GenuineIntel
Model name: Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz
CPU family: 6
Model: 42
Thread(s) per core: 2
Core(s) per socket: 4
Socket(s): 1
Stepping: 7
CPU max MHz: 3800.0000
CPU min MHz: 1600.0000
BogoMIPS: 6784.75
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mc
a cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ht
tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon p
ebs bts rep_good nopl xtopology nonstop_tsc cpuid aperf
mperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est t
m2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcn
t tsc_deadline_timer aes xsave avx lahf_lm epb pti ssbd
ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid
xsaveopt dtherm ida arat pln pts md_clear flush_l1d
Virtualization features:
Virtualisation: VT-x
Caches (sum of all):
L1d: 128 KiB (4 instances)
L1i: 128 KiB (4 instances)
L2: 1 MiB (4 instances)
L3: 8 MiB (1 instance)
NUMA:
NUMA node(s): 1
NUMA node0 CPU(s): 0-7
Vulnerabilities:
Gather data sampling: Not affected
Itlb multihit: KVM: Mitigation: VMX disabled
L1tf: Mitigation; PTE Inversion; VMX conditional cache flushe
s, SMT vulnerable
Mds: Mitigation; Clear CPU buffers; SMT vulnerable
Meltdown: Mitigation; PTI
Mmio stale data: Unknown: No mitigations
Retbleed: Not affected
Spec rstack overflow: Not affected
Spec store bypass: Mitigation; Speculative Store Bypass disabled via prctl
and seccomp
Spectre v1: Mitigation; usercopy/swapgs barriers and __user pointer
sanitization
Spectre v2: Mitigation; Retpolines; IBPB conditional; IBRS_FW; STIB
P conditional; RSB filling; PBRSB-eIBRS Not affected; B
HI Not affected
Srbds: Not affected
Tsx async abort: Not affected

AVX2 (Advanced Vector Extensions 2) is an expansion of the AVX instruction set introduced by Intel and AMD. It provides additional instructions to accelerate integer vector operations. AVX2 builds upon the foundation of AVX, offering higher performance and efficiency for certain computational workloads.

AVX2 introduces several new features, including:

  • Support for 256-bit integer vector operations: AVX2 extends the width of vector registers from 128 bits to 256 bits, allowing for more data to be processed simultaneously.
  • New integer vector instructions: AVX2 adds new instructions for integer vector arithmetic, bitwise operations, and vector shuffles, providing - enhanced capabilities for tasks such as image processing, cryptography, and scientific computing.
  • Enhanced gather and scatter operations: AVX2 includes new instructions for indexed memory operations, enabling more efficient data movement - between memory and vector registers.

CPUs that support AVX2 typically belong to newer generations and include various Intel and AMD processors released after 2013. Some examples of CPUs that support AVX2 include:

  • Intel Haswell (4th generation Core processors) and newer.
  • Intel Broadwell, Skylake, Kaby Lake, Coffee Lake, Comet Lake, and later microarchitectures.
  • AMD Ryzen processors (starting with the first-generation Ryzen CPUs).
  • AMD Ryzen Threadripper processors.
  • AMD EPYC processors.

These processors offer improved performance for workloads that can leverage AVX2 instructions, making them well-suited for tasks involving heavy computational workloads, such as machine learning, numerical simulations, and media processing.

pyenv install notes

https://github.com/pyenv/pyenv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ curl https://pyenv.run | bash

Cloning into '~/.pyenv'...


WARNING: seems you still have not added 'pyenv' to the load path.

# Load pyenv automatically by appending
# the following to
# ~/.bash_profile if it exists, otherwise ~/.profile (for login shells)
# and ~/.bashrc (for interactive shells) :

export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

# Restart your shell for the changes to take effect.

# Load pyenv-virtualenv automatically by adding
# the following to ~/.bashrc:

eval "$(pyenv virtualenv-init -)"