Solution follows, I solved this problem:
Good thing I figured out the issue after I've now wasted at least 6 hours debugging this issue. Turns out there's no VS bug, the only bug is that I am an idiot. The issue turned out to be that my code was referencing external .dlls that were not installed in the GAC. For whatever reason I got no error message or warning and my event receiver was simply not called. I'm not sure how SP handles it but that's what happened.
It is easily solved by either dragging your .dlls into the GAC (C:/Windows/assembly) or by going to the Package (SP Solution), clicking advanced, and adding your assemblies as "additional assemblies" with deployment target = globalassemblycache.
UPDATE: Problem Through a lot of trial and error I have discovered that if I leave my method definitions blank, except for calling base() (e.g. if I leave itemAdded and itemUpdated empty) THEN and only then does my breakpoint get hit. I am having a hard time accepting this as anything other than a bug but I can't figure out what the bug is, if any, and I don't understand why or how this could occur. Thus far I have tried it out on two different site collections but not on a different web application. Wtf is going on?
Scenario: Document library event receiver. Default content types. Microsoft word document was chosen as the type when I setup the document library. I am adding a text file to the document library through the UI "Add document" and expecting it to fire an event and hit my breakpoint.
Process: My general debugging process for event receivers goes: end the vsshostp4 process via task manager. Deploy as a farm solution with active deployment configuration set to no activation. Attach to following processes: SPUCWorkers, w3wps. Manually activate the feature through the sharepoint site UI.
Results: I am able to hit breakpoints for itemAdded and itemDeleted but never for itemUpdated.
Weird behavior: If I name my method "itemUpdating" and then rename it back to itemUpdated, then do refactoring in Visual Studio, I get an error. The error says that the itemUpdated method already exists which makes no sense. That method doesn't exist anywhere else in my class.
Code that registers the event handlers. It programmatically attaches to a single document library. I'm pretty sure it works as it has in the past. _updatedEventType etc are correctly defined as SPEventReceiverTypes:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
//Register event receivers
SPList list = oWeb.Lists[docName];
oWeb.Lists[docName].EventReceivers.Add(_updatedEventType, Assembly.GetExecutingAssembly().FullName, "MyReferencesReceiver.LibraryEventReceiver.LibraryEventReceiver");
oWeb.Lists[docName].EventReceivers.Add(_addedEventType, Assembly.GetExecutingAssembly().FullName, "MyReferencesReceiver.LibraryEventReceiver.LibraryEventReceiver");
oWeb.Lists[docName].EventReceivers.Add(_deletedEventType, Assembly.GetExecutingAssembly().FullName, "MyReferencesReceiver.LibraryEventReceiver.LibraryEventReceiver");
Code that should get called for document library events:
public override void ItemUpdated(SPItemEventProperties properties)
edit: This is going to sound crazy but it just completely flipped. Now it will not hit the itemAdded breakpoint but it will hit the itemUpdated breakpoint.