Enable the profiling of C functions (builtins and extensions)
diff --git a/Lib/bdb.py b/Lib/bdb.py
index 11ed212..19a9722 100644
--- a/Lib/bdb.py
+++ b/Lib/bdb.py
@@ -52,6 +52,12 @@
             return self.dispatch_return(frame, arg)
         if event == 'exception':
             return self.dispatch_exception(frame, arg)
+        if event == 'c_call':
+            return self.trace_dispatch
+        if event == 'c_exception':
+            return self.trace_dispatch
+        if event == 'c_return':
+            return self.trace_dispatch
         print 'bdb.Bdb.dispatch: unknown debugging event:', repr(event)
         return self.trace_dispatch
 
diff --git a/Lib/profile.py b/Lib/profile.py
index cf22377..99a5b62 100755
--- a/Lib/profile.py
+++ b/Lib/profile.py
@@ -163,6 +163,7 @@
         self.timings = {}
         self.cur = None
         self.cmd = ""
+        self.c_func_name = ""
 
         if bias is None:
             bias = self.bias
@@ -214,6 +215,9 @@
         t = timer()
         t = t[0] + t[1] - self.t - self.bias
 
+        if event == "c_call":
+            self.c_func_name = arg
+
         if self.dispatch[event](self, frame,t):
             t = timer()
             self.t = t[0] + t[1]
@@ -227,7 +231,11 @@
     def trace_dispatch_i(self, frame, event, arg):
         timer = self.timer
         t = timer() - self.t - self.bias
-        if self.dispatch[event](self, frame,t):
+
+        if event == "c_call":
+            self.c_func_name = arg
+
+        if self.dispatch[event](self, frame, t):
             self.t = timer()
         else:
             self.t = timer() - t  # put back unrecorded delta
@@ -238,6 +246,10 @@
     def trace_dispatch_mac(self, frame, event, arg):
         timer = self.timer
         t = timer()/60.0 - self.t - self.bias
+
+        if event == "c_call":
+            self.c_func_name = arg
+
         if self.dispatch[event](self, frame, t):
             self.t = timer()/60.0
         else:
@@ -249,6 +261,9 @@
         get_time = self.get_time
         t = get_time() - self.t - self.bias
 
+        if event == "c_call":
+            self.c_func_name = arg
+
         if self.dispatch[event](self, frame, t):
             self.t = get_time()
         else:
@@ -291,6 +306,17 @@
             timings[fn] = 0, 0, 0, 0, {}
         return 1
 
+    def trace_dispatch_c_call (self, frame, t):
+        fn = ("", 0, self.c_func_name)
+        self.cur = (t, 0, 0, fn, frame, self.cur)
+        timings = self.timings
+        if timings.has_key(fn):
+            cc, ns, tt, ct, callers = timings[fn]
+            timings[fn] = cc, ns+1, tt, ct, callers
+        else:
+            timings[fn] = 0, 0, 0, 0, {}
+        return 1
+
     def trace_dispatch_return(self, frame, t):
         if frame is not self.cur[-2]:
             assert frame is self.cur[-2].f_back, ("Bad return", self.cur[-3])
@@ -333,6 +359,9 @@
         "call": trace_dispatch_call,
         "exception": trace_dispatch_exception,
         "return": trace_dispatch_return,
+        "c_call": trace_dispatch_c_call,
+        "c_exception": trace_dispatch_exception,
+        "c_return": trace_dispatch_return,
         }
 
 
diff --git a/Lib/test/output/test_profile b/Lib/test/output/test_profile
index 917a18e..b46bb6a 100644
--- a/Lib/test/output/test_profile
+++ b/Lib/test/output/test_profile
@@ -1,9 +1,12 @@
 test_profile
-         53 function calls in 1.000 CPU seconds
+         74 function calls in 1.000 CPU seconds
 
    Ordered by: standard name
 
    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
+       12    0.000    0.000    0.012    0.001 :0(hasattr)
+        8    0.000    0.000    0.000    0.000 :0(range)
+        1    0.000    0.000    0.000    0.000 :0(setprofile)
         1    0.000    0.000    1.000    1.000 <string>:1(?)
         0    0.000             0.000          profile:0(profiler)
         1    0.000    0.000    1.000    1.000 profile:0(testfunc())
diff --git a/Lib/test/test_profilehooks.py b/Lib/test/test_profilehooks.py
index ac8ebd8..53f882a 100644
--- a/Lib/test/test_profilehooks.py
+++ b/Lib/test/test_profilehooks.py
@@ -11,7 +11,10 @@
         self.events = []
 
     def callback(self, frame, event, arg):
-        self.add_event(event, frame)
+        if (event == "call"
+            or event == "return"
+            or event == "exception"):
+            self.add_event(event, frame)
 
     def add_event(self, event, frame=None):
         """Add an event to the log."""
@@ -56,10 +59,16 @@
         self.testcase.fail(
             "the profiler should never receive exception events")
 
+    def trace_pass(self, frame):
+        pass
+
     dispatch = {
         'call': trace_call,
         'exception': trace_exception,
         'return': trace_return,
+        'c_call': trace_pass,
+        'c_return': trace_pass,
+        'c_exception': trace_pass,
         }