CocoaHTTPServer icon indicating copy to clipboard operation
CocoaHTTPServer copied to clipboard

HTTPServer: -Dealloc causes memory corruption

Open bdkjones opened this issue 8 years ago • 6 comments
trafficstars

Hi Robbie,

Summary:

The call to -stop:NO in -dealloc of HTTPServer.m can produce memory corruption because there is no check to see if the server has already been stopped.

Steps to Reproduce:

  1. Spin up an instance of HTTPServer as normal.
  2. Call [myServerInstance stop:NO]
  3. Call [myServerInstance release]
  4. Set myServerInstance = nil

(steps 3 and 4 assume you're working in a manual reference counting environment.) You will need to repeat this process several times because the issue only manifests sometimes.

What's Going On:

We call -stop on our server instance just before releasing it, which triggers the -dealloc method of HTTPServer. That dealloc method calls -stop again, regardless of whether the server is running or not.

About 4 out of 5 times, there is no problem. But approximately 1 out of 5 times, ARC produces a warning that informs you, "memory address X is supposed to hold address 0x000012345 but instead holds address 0x0000987665. This is likely incorrect usage of objc_store_weak() or objc_load_weak(), break on objc_weak_error to debug."

Breaking on that symbol shows that `[HTTPServer dealloc] is the last method in the stack trace before the warning is produced.

How I Fixed It:

I removed my own call to [myServerInstance stop:NO] and just released and nilled the instance instead. -dealloc still calls -stop:NO, but that method is now only called once. After doing this, I am no longer able to produce the ARC warning, no matter how many times I stop and recreate the server instance.

Suggested Permanent Fix:

The -dealloc method should really only call -stop if the server is running.

bdkjones avatar Dec 10 '16 01:12 bdkjones

Actually, a more robust solution would be to have -stop return immediately if the server isn't running. That way, if the method is called more than once from anywhere, this problem is avoided.

bdkjones avatar Dec 10 '16 01:12 bdkjones

Nice bug report! Want to submit a PR?

chrisballinger avatar Dec 12 '16 01:12 chrisballinger

Mother of god...I thought this project was dead and buried. I just filed the report to procrastinate on customer support emails.

bdkjones avatar Dec 13 '16 21:12 bdkjones

Hahahahahaha. I mean, it is, but plenty of people are still using it.

chrisballinger avatar Dec 13 '16 22:12 chrisballinger

Actually the problem is the underlying NSNetService, see http://www.openradar.me/28943305 for more information. The workaround is to nil out the delegate before releasing. In HTTPServer.m this is in 'unpublishBonjour'. The bonjourBlock is called synchronously so this should be good.

[[self class] performBonjourBlock:bonjourBlock];

[netService setDelegate:nil]; // added this line to workaround apples weaksauce

netService = nil;

pwnified avatar Jan 03 '17 08:01 pwnified

Thanks!

bdkjones avatar Jan 04 '17 08:01 bdkjones