Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Neuroglancer crashing while browsing tags on Chrome/Mac #685

Open
bdpedigo opened this issue Dec 14, 2024 · 8 comments
Open

Neuroglancer crashing while browsing tags on Chrome/Mac #685

bdpedigo opened this issue Dec 14, 2024 · 8 comments

Comments

@bdpedigo
Copy link

I am having an issue with Neuroglancer crashing in Chrome on Mac.

Here is a link that at least one other person has been able to replicate the issue with. Should be able to view after agreeing to TOS, please let me know if you have any issues.

I get the crash after bouncing around the tagged annotation points (using "[" and "]") for several minutes. Unfortunately we have not yet found a way to make it happen immediately.

My Chrome crash logs look something like this:

Operating system: Mac OS X
                  13.6.1 22G313
CPU: arm64
     12 CPUs

GPU: UNKNOWN

Crash reason:  EXC_BREAKPOINT / 0x00000001
Crash address: 0x11f206fbc
Crash parameters:
    value: 10	description: 
    value: 90177537	description: 
    value: 4817186748	description: 
Process uptime: 277327 seconds

Thread 6 (crashed)
 0  Google Chrome Framework + 0x652efbc
     x0 = 0x0000000171b01908    x1 = 0x000000000a600000
     x2 = 0x0000000000008503    x3 = 0x0000000000010000
     x4 = 0x0000000000010000    x5 = 0x0000000171b01b60
     x6 = 0x0000000171b01b5f    x7 = 0x0000000085845dd1
     x8 = 0x0000000000000000    x9 = 0x200074696d6d6f63
    x10 = 0x0000000000000053   x11 = 0x00000000000016b8
    x12 = 0x0000000000001fae   x13 = 0x0000000000001f79
    x14 = 0x0000000000002000   x15 = 0x0000000000002000
    x16 = 0x000000019d6ebac0   x17 = 0x0000000000000000
    x18 = 0x0000000000000000   x19 = 0x000000000a600000
    x20 = 0x00000001248ab2c0   x21 = 0x00000001f8758658
    x22 = 0x0000000000000000   x23 = 0x0000000171b01b5f
    x24 = 0x0000000000010000   x25 = 0x0000000000000010
    x26 = 0x000000000a4d18c8   x27 = 0x0000000000000002
    x28 = 0x0000000000004000    fp = 0x0000000171b01910
     lr = 0x000000011f206fbc    sp = 0x0000000171b01900
     pc = 0x000000011f206fbc
    Found by: given as instruction pointer in context
 1  Google Chrome Framework + 0x652efb8
     fp = 0x0000000171b01920    lr = 0x000000011f206fd4
     sp = 0x0000000171b01920    pc = 0x000000011f206fbc
    Found by: previous frame's frame pointer
 2  Google Chrome Framework + 0x652efd0
     fp = 0x0000000171b01930    lr = 0x000000011f206fe0
     sp = 0x0000000171b01930    pc = 0x000000011f206fd4
    Found by: previous frame's frame pointer
 3  Google Chrome Framework + 0x652efdc
     fp = 0x0000000171b01990    lr = 0x000000011f20a1ac
     sp = 0x0000000171b01940    pc = 0x000000011f206fe0
    Found by: previous frame's frame pointer
 4  Google Chrome Framework + 0x65321a8
     fp = 0x0000000171b019c0    lr = 0x000000011f20973c
     sp = 0x0000000171b019a0    pc = 0x000000011f20a1ac
    Found by: previous frame's frame pointer
 5  Google Chrome Framework + 0x6531738
     fp = 0x0000000171b01a40    lr = 0x000000011f2082dc
     sp = 0x0000000171b019d0    pc = 0x000000011f20973c
    Found by: previous frame's frame pointer
 6  Google Chrome Framework + 0x65302d8
     fp = 0x0000000171b01b40    lr = 0x0000000119552f20
     sp = 0x0000000171b01a50    pc = 0x000000011f2082dc
    Found by: previous frame's frame pointer
 7  Google Chrome Framework + 0x87af1c
     fp = 0x0000000171b01bd0    lr = 0x000000011f20ccf4
     sp = 0x0000000171b01b50    pc = 0x0000000119552f20
    Found by: previous frame's frame pointer
 8  Google Chrome Framework + 0x6534cf0
     fp = 0x0000000171b01c20    lr = 0x000000011a42a2c4
     sp = 0x0000000171b01be0    pc = 0x000000011f20ccf4
    Found by: previous frame's frame pointer
 9  Google Chrome Framework + 0x17522c0
     fp = 0x0000000171b01cc0    lr = 0x000000011c1036f4
     sp = 0x0000000171b01c30    pc = 0x000000011a42a2c4
    Found by: previous frame's frame pointer
10  Google Chrome Framework + 0x342b6f0
     fp = 0x0000000171b01cf0    lr = 0x0000000118cebc54
     sp = 0x0000000171b01cd0    pc = 0x000000011c1036f4
    Found by: previous frame's frame pointer
11  Google Chrome Framework + 0x13c50
     fp = 0x0000000171b01d40    lr = 0x000000011c104be0
     sp = 0x0000000171b01d00    pc = 0x0000000118cebc54
    Found by: previous frame's frame pointer
12  Google Chrome Framework + 0x342cbdc
     fp = 0x0000000171b01df0    lr = 0x0000000119caf308
     sp = 0x0000000171b01d50    pc = 0x000000011c104be0
    Found by: previous frame's frame pointer
13  Google Chrome Framework + 0xfd7304
     fp = 0x0000000171b01fd0    lr = 0x000000012019a060
     sp = 0x0000000171b01e00    pc = 0x0000000119caf308
    Found by: previous frame's frame pointer
14  Google Chrome Framework + 0x74c205c
     fp = 0x0000000171b02010    lr = 0x000000012019a4bc
     sp = 0x0000000171b01fe0    pc = 0x000000012019a060
    Found by: previous frame's frame pointer
15  Google Chrome Framework + 0x74c24b8
     fp = 0x0000000171b02420    lr = 0x000000012019cbfc
     sp = 0x0000000171b02020    pc = 0x000000012019a4bc
    Found by: previous frame's frame pointer
16  Google Chrome Framework + 0x74c4bf8
     fp = 0x0000000171b02600    lr = 0x000000012019d9c0
     sp = 0x0000000171b02430    pc = 0x000000012019cbfc
    Found by: previous frame's frame pointer
17  Google Chrome Framework + 0x74c59bc
     fp = 0x0000000171b027c0    lr = 0x000000012019d5c0
     sp = 0x0000000171b02610    pc = 0x000000012019d9c0
    Found by: previous frame's frame pointer
18  Google Chrome Framework + 0x74c55bc
     fp = 0x0000000171b02800    lr = 0x0000000120197440
     sp = 0x0000000171b027d0    pc = 0x000000012019d5c0
    Found by: previous frame's frame pointer
19  Google Chrome Framework + 0x74bf43c
     fp = 0x0000000171b02820    lr = 0x000000012019808c
     sp = 0x0000000171b02810    pc = 0x0000000120197440
    Found by: previous frame's frame pointer
20  Google Chrome Framework + 0x74c0088
     fp = 0x0000000171b028a0    lr = 0x00000001199db178
     sp = 0x0000000171b02830    pc = 0x000000012019808c
    Found by: previous frame's frame pointer
21  Google Chrome Framework + 0xd03174
     fp = 0x0000000171b02930    lr = 0x0000000119508eb8
     sp = 0x0000000171b028b0    pc = 0x00000001199db178
    Found by: previous frame's frame pointer
22  Google Chrome Framework + 0x830eb4
     fp = 0x0000000171b02c70    lr = 0x00000001195082d4
     sp = 0x0000000171b02940    pc = 0x0000000119508eb8
    Found by: previous frame's frame pointer
23  Google Chrome Framework + 0x8302d0
     fp = 0x0000000171b02f10    lr = 0x00000001195061e0
     sp = 0x0000000171b02c80    pc = 0x00000001195082d4
    Found by: previous frame's frame pointer
24  Google Chrome Framework + 0x82e1dc
     fp = 0x0000000171b02f30    lr = 0x000000011a6c330c
     sp = 0x0000000171b02f20    pc = 0x00000001195061e0
    Found by: previous frame's frame pointer
25  Google Chrome Framework + 0x19eb308
     fp = 0x0000000171b02f70    lr = 0x000000011a6c323c
     sp = 0x0000000171b02f40    pc = 0x000000011a6c330c
    Found by: previous frame's frame pointer
26  Google Chrome Framework + 0x19eb238
     fp = 0x0000000171b02fc0    lr = 0x000000011a141bf4
     sp = 0x0000000171b02f80    pc = 0x000000011a6c323c
    Found by: previous frame's frame pointer
27  Google Chrome Framework + 0x1469bf0
     fp = 0x0000000171b02fe0    lr = 0x000000019d6bffa8
     sp = 0x0000000171b02fd0    pc = 0x000000011a141bf4
    Found by: previous frame's frame pointer
28  libsystem_pthread.dylib + 0x6fa4
     fp = 0x0000000000000000    lr = 0x000000019d6bada0
     sp = 0x0000000171b02ff0    pc = 0x000000019d6bffa8
    Found by: previous frame's frame pointer

Some observations: we think this has something to do with Chrome history. I've observed that after one of these crashes, my chrome profile can become unstable and start crashing at random times even while not using Neuroglancer (and with nothing else consuming much memory on my machine). The only solution to this I have found is to make a new chrome profile, or clear history in the current one.

Similarly, I've observed that opening Chrome history can also crash chrome after I've experienced one of these crashes in Neuroglancer.

Please let me know if there's any other information I can provide to help reproduce or debug.

@bdpedigo
Copy link
Author

If it helps, Chrome version is:
Version 131.0.6778.140 (Official Build) (arm64)

@ceesem
Copy link

ceesem commented Dec 14, 2024

Just looking at this a bit, this kind of annotation-rich state produces a URL that is very, very large. I can seem to copy only 629,772 characters out of the URL or history, but I don't think that is at all complete and the history is storing the whole URL. Chrome history is updating maybe once every second or two in workflows like this. It is easy to get many hundreds or thousands of MB-scale URLs stored in history in just 10 or 20 minutes of working.

@jbms
Copy link
Collaborator

jbms commented Dec 14, 2024

While stopgaps like supporting compression in the URL syntax may help, ultimately the only real solution is to store the annotation list outside of the Neuroglancer state, either in neuroglancer precomputed format if read-only access is sufficient, or in some new format/server if read-write access to the annotations is needed.

@ceesem
Copy link

ceesem commented Dec 14, 2024

Read-only access is not sufficient for these use cases, unfortunately, and there are no performance issues within neuroglancer for using it this way. The amount of time to build a novel solution that simply recreates existing functionality is not feasible with current resources, nor does it suit the use case for rapid analysis to have to maintain yet another managed server. We frequently encounter a pipeline where a person does local analysis, generates thousands of annotations to reflect that analysis, uses tags to rapidly validate results in the full context of the EM volume, and then returns the data for subsequent analysis via a state server. In many cases, thousands of points can reflect relatively only an hour or two of work to validate, and both should be visualized together and do not need to be spread across multiple sessions.

Neuroglancer itself handles high-annotation states fine, as does the state-server method of saving and retrieving JSON, it is only the synchronization of state with URL that causes the memory issues. During these situations, we already rely on the state-sharing approach rather than URL copying since the URLs are too long to robustly copy, thus URL synchronization is not serving the same compatibility goal as in smaller states. While I understand this would not be a default option (particularly as it only applies if a state sharing URL is set), it feels like there could be some optional mechanism that gracefully passes from URL synchronization for modest states to truncated URLs + sharing (with a warning in the UI somehow). Or perhaps a flag in the state JSON itself about synchronization so that one could turn it off in these particular situations, again with a warning in the UI.

I wonder if it wouldn't be possible to open a persistent connection to a state server ID, where rather than download it once, neuroglancer could push states (or, better, state changes) in some way to keep that state ID up to date. That way, the URL would continue to be up to date or nearly up to date for sharing purposes, but we would also get the value of the short links. It would be particularly ideal if combined with state-level undo, since this would make the URL history no longer reflect state history.

@fcollman
Copy link
Contributor

I can see that this large scale annotation editing might be the source of some of the crash reports i've been hearing about, but they have been pretty wide spread at the Allen the last week or so, so i want to at least entertain the possibility that this isn't just about editing large scale annotation lists.

On the annotation read/write server question, what would the skeleton of an API look like that would be easiest to implement such a feature utilizing the existing annotation infrastructure?

@fcollman
Copy link
Contributor

but also is this a chrome bug or is neuroglancer abusing chrome history in some fashion that it isn't designed to do? If its about the history it shouldn't really be able memory management, unless somehow the history is stored in memory and not on disk.

@jbms
Copy link
Collaborator

jbms commented Dec 16, 2024

Neuroglancer uses history.replaceState which is supposed to avoid creating a new history entry, and that is the case as far as the back/forward buttons, but in the global chrome history additional entries do seem to get created. Surely it is a crhome bug but I imagine the history APIs don't get tested with such large URLs.

Just adding an option not to store the state in the URL, such that saving to the state server would be required, would be easy enough, not sure how well that would actually address your proofreading use case.

As far as automatically "synchronizing" the Neuroglancer state to a state server, and potentially storing the history, certainly that would be a useful feature. I prototyped that with Google Drive some years ago, but dropped it because limitations in the Google Drive APIs meant that sharing with another user couldn't work in a reasonable way.

That could certainly be implemented with a change to your state server --- just synchronizing the latest state would probably be minimal effort, storing the history would likely be more complicated.

In general I think state synchronization with or without history is useful, but for dealing with annotations, I think it would be more natural and convenient in most cases to store the annotations separately with their own history independent of the Neuroglancer state used to view those annotations, as that would allow multiple users to edit the same annotation table simultaneously.

I previously discussed with Forrest and others that idea of a general "log-structured" server for Neuroglancer, where the server allows users to create "logs" that support the following operations:

  • appending a record, which contains arbitrary payload tagged with the username and monotonic timestamp
  • reading all records
  • efficiently watching or polling for writes by other users

This would enable read-write storage of a number of things to be implemented entirely client-side:

  • Annotation tables
  • Neuroglancer state history
  • Small agglomeration graphs

The key limitation would be that the total size of the log could not be too large, e.g. a few MB, or maybe 100 MB at most, since clients will always download the entire log, and then reconstruct the state at the requested timestamp by iterating over all of the entries. But that would probably still cover a lot of use cases, and by treating the log as a delta on top of some large base annotation table or base agglomeration graph you could go even further.

As far as integration into Neuroglancer --- Neuroglancer already has an internal API for read-write annotation sources, which is used for a Google-internal brainmaps:// annotation source and for a DVID annotation source, but nothing currently to support the concept of a history. However, support for history needs to be solved anyway to acommodate graphene/CAVE.

@wanqingy
Copy link

wanqingy commented Dec 16, 2024

Hi!

I’ve also encountered Chrome crashing while viewing a large number of skeletons in Neuroglancer (without annotations or proofreading). Unfortunately, I don’t have a publicly shareable link at the moment.

From my experience, the first crash appeared to be partially memory-related. When loading the same number of skeletons in Safari, I received a warning pop-up stating that my system had run out of application memory. However, no such warning appeared in Chrome—it just crashed.

What’s similar to Ben’s experience is that after the initial crash, Chrome started crashing frequently (every few minutes), even when I wasn’t working with any NG links. I didn’t get a chance to explore the History tab, but I’m wondering if there might be a broader underlying issue causing this behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants