Skip to content

Commit 26731fb

Browse files
committed
[oslog-overlay-fixes] Adopt os_log_pack
Adopt libtrace os_log_pack in order to more accurately provide logging data to libtrace. This allows the overlay code to supply the caller's pc to libtrace and fix `log show --source` to show the caller's source information when called from Swift. Addresses radar: <rdar://problem/29195869> os_log in Swift via overlay does not include 'source' filename/line number in `log stream`
1 parent 5ed0efa commit 26731fb

File tree

3 files changed

+54
-27
lines changed

3 files changed

+54
-27
lines changed

stdlib/public/SDK/os/os_log.m

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,7 @@
2121
#include <wchar.h>
2222

2323
#include "os_trace_blob.h"
24-
25-
#ifndef os_fastpath
26-
#define os_fastpath(x) ((__typeof__(x))OS_EXPECT((long)(x), ~0l))
27-
#endif
28-
#ifndef os_slowpath
29-
#define os_slowpath(x) ((__typeof__(x))OS_EXPECT((long)(x), 0l))
30-
#endif
31-
#ifndef os_likely
32-
#define os_likely(x) OS_EXPECT(!!(x), 1)
33-
#endif
34-
#ifndef os_unlikely
35-
#define os_unlikely(x) OS_EXPECT(!!(x), 0)
36-
#endif
37-
38-
#ifndef MIN
39-
#define MIN(a, b) (((a)<(b))?(a):(b))
40-
#endif
24+
#include "thunks.h"
4125

4226
#define OST_FORMAT_MAX_STRING_SIZE 1024
4327
#define OS_LOG_FMT_MAX_CMDS 48
@@ -92,13 +76,33 @@
9276
uint8_t cmd_data[];
9377
} os_log_fmt_cmd_s, *os_log_fmt_cmd_t;
9478

95-
9679
typedef struct os_log_fmt_hdr_s {
9780
os_log_fmt_hdr_flags_t hdr_flags;
9881
uint8_t hdr_cmd_cnt;
9982
uint8_t hdr_data[];
10083
} os_log_fmt_hdr_s, *os_log_fmt_hdr_t;
10184

85+
typedef struct os_log_pack_s {
86+
uint64_t olp_continuous_time;
87+
struct timespec olp_wall_time;
88+
const void *olp_mh;
89+
const void *olp_pc;
90+
const char *olp_format;
91+
uint8_t olp_data[0];
92+
} os_log_pack_s, *os_log_pack_t;
93+
94+
API_AVAILABLE(macosx(10.12.4), ios(10.3), tvos(10.2), watchos(3.2))
95+
size_t
96+
_os_log_pack_size(size_t os_log_format_buffer_size);
97+
98+
API_AVAILABLE(macosx(10.12.4), ios(10.3), tvos(10.2), watchos(3.2))
99+
uint8_t *
100+
_os_log_pack_fill(os_log_pack_t pack, size_t size, int saved_errno, const void *dso, const char *fmt);
101+
102+
API_AVAILABLE(macosx(10.12.4), ios(10.3), tvos(10.2), watchos(3.2))
103+
void
104+
os_log_pack_send(os_log_pack_t pack, os_log_t log, os_log_type_t type);
105+
102106
static inline void
103107
_os_log_encode_arg(os_trace_blob_t ob, os_log_fmt_cmd_t cmd, const void *data)
104108
{
@@ -299,17 +303,37 @@
299303

300304
__attribute__((__visibility__("default")))
301305
void
302-
_swift_os_log(void *dso, os_log_t oslog, os_log_type_t type, const char *format, va_list args)
306+
_swift_os_log(void *dso, void *retaddr, os_log_t oslog, os_log_type_t type, const char *format, va_list args)
303307
{
304-
int save_errno = errno; // %m
308+
int saved_errno = errno; // %m
305309
char buf[OS_LOG_FMT_BUF_SIZE];
306310
os_trace_blob_s ob = {
307311
.ob_s = buf,
308312
.ob_size = OS_LOG_FMT_BUF_SIZE,
309313
.ob_binary = true
310314
};
311315

312-
if (_os_log_encode(buf, format, args, save_errno, &ob)) {
313-
_os_log_impl(dso, oslog, type, format, (uint8_t *)buf, ob.ob_len);
316+
if (_os_log_encode(buf, format, args, saved_errno, &ob)) {
317+
// Use os_log_pack_send where available.
318+
if (os_log_pack_send) {
319+
size_t sz = _os_log_pack_size(ob.ob_len);
320+
union { os_log_pack_s pack; uint8_t buf[OS_LOG_FMT_BUF_SIZE + sizeof(os_log_pack_s)]; } u;
321+
// _os_log_encode has already packed `saved_errno` into a OSLF_CMD_TYPE_SCALAR command
322+
// as the OSLF_CMD_TYPE_ERRNO does not deploy backwards, so passes zero for errno here.
323+
uint8_t *ptr = _os_log_pack_fill(&u.pack, sz, 0, dso, format);
324+
u.pack.olp_pc = retaddr;
325+
memcpy(ptr, buf, ob.ob_len);
326+
os_log_pack_send(&u.pack, oslog, type);
327+
} else {
328+
_os_log_impl(dso, oslog, type, format, (uint8_t *)buf, ob.ob_len);
329+
}
314330
}
315331
}
332+
333+
__attribute__((__visibility__("default")))
334+
void *
335+
_swift_os_log_return_address(void)
336+
{
337+
return __builtin_return_address(1);
338+
}
339+

stdlib/public/SDK/os/os_log.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ public func os_log(
2323
_ args: CVarArg...)
2424
{
2525
guard log.isEnabled(type: type) else { return }
26+
let ra = _swift_os_log_return_address()
2627

2728
message.withUTF8Buffer { (buf: UnsafeBufferPointer<UInt8>) in
2829
// Since dladdr is in libc, it is safe to unsafeBitCast
29-
// the cstring argument type.
30+
// the cstring argument type.
3031
let str = unsafeBitCast(buf.baseAddress!, to: UnsafePointer<Int8>.self)
3132
withVaList(args) { valist in
32-
_swift_os_log(dso, log, type, str, valist)
33+
_swift_os_log(dso, ra, log, type, str, valist)
3334
}
3435
}
3536
}

stdlib/public/SwiftShims/OSOverlayShims.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
#include <os/log.h>
1717
#include <stdarg.h>
1818

19-
extern void _swift_os_log(const void * _Nullable dso, os_log_t _Nonnull oslog,
20-
os_log_type_t type, const char * _Nonnull format,
21-
va_list args);
19+
extern const void * _Nullable _swift_os_log_return_address(void);
20+
21+
extern void _swift_os_log(const void * _Nullable dso, const void * _Nullable retaddr,
22+
os_log_t _Nonnull oslog, os_log_type_t type,
23+
const char * _Nonnull format, va_list args);
2224

2325
static inline os_log_t _Nonnull
2426
_swift_os_log_default(void) {

0 commit comments

Comments
 (0)