Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
c02dce53
Commit
c02dce53
authored
Nov 07, 2016
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add KJ_WIN32 macro, the Windows equivalent of KJ_SYSCALL.
parent
c79b6d09
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
170 additions
and
25 deletions
+170
-25
debug.c++
c++/src/kj/debug.c++
+91
-8
debug.h
c++/src/kj/debug.h
+79
-17
No files found.
c++/src/kj/debug.c++
View file @
c02dce53
...
...
@@ -27,6 +27,13 @@
#if _WIN32
#define strerror_r(errno,buf,len) strerror_s(buf,len,errno)
#define NOMINMAX 1
#define WIN32_LEAN_AND_MEAN 1
#define NOSERVICE 1
#define NOMCX 1
#define NOIME 1
#include <windows.h>
#include "windows-sanity.h"
#endif
namespace
kj
{
...
...
@@ -125,6 +132,38 @@ Exception::Type typeOfErrno(int error) {
}
}
#if _WIN32
Exception
::
Type
typeOfWin32Error
(
DWORD
error
)
{
switch
(
error
)
{
// TODO(now): This needs more work.
case
WSAETIMEDOUT
:
return
Exception
::
Type
::
OVERLOADED
;
case
WSAENOTCONN
:
case
WSAECONNABORTED
:
case
WSAECONNREFUSED
:
case
WSAECONNRESET
:
case
WSAEHOSTDOWN
:
case
WSAEHOSTUNREACH
:
case
WSAENETDOWN
:
case
WSAENETRESET
:
case
WSAENETUNREACH
:
return
Exception
::
Type
::
DISCONNECTED
;
case
WSAEOPNOTSUPP
:
case
WSAENOPROTOOPT
:
case
WSAENOTSOCK
:
// This is really saying "syscall not implemented for non-sockets".
return
Exception
::
Type
::
UNIMPLEMENTED
;
default
:
return
Exception
::
Type
::
FAILED
;
}
}
#endif // _WIN32
enum
DescriptionStyle
{
LOG
,
ASSERTION
,
...
...
@@ -132,7 +171,8 @@ enum DescriptionStyle {
};
static
String
makeDescriptionImpl
(
DescriptionStyle
style
,
const
char
*
code
,
int
errorNumber
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
const
char
*
sysErrorString
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
KJ_STACK_ARRAY
(
ArrayPtr
<
const
char
>
,
argNames
,
argValues
.
size
(),
8
,
64
);
if
(
argValues
.
size
()
>
0
)
{
...
...
@@ -205,13 +245,21 @@ static String makeDescriptionImpl(DescriptionStyle style, const char* code, int
#if __USE_GNU
char
buffer
[
256
];
if
(
style
==
SYSCALL
)
{
sysErrorArray
=
strerror_r
(
errorNumber
,
buffer
,
sizeof
(
buffer
));
if
(
sysErrorString
==
nullptr
)
{
sysErrorArray
=
strerror_r
(
errorNumber
,
buffer
,
sizeof
(
buffer
));
}
else
{
sysErrorArray
=
sysErrorString
;
}
}
#else
char
buffer
[
256
];
if
(
style
==
SYSCALL
)
{
strerror_r
(
errorNumber
,
buffer
,
sizeof
(
buffer
));
sysErrorArray
=
buffer
;
if
(
sysErrorString
==
nullptr
)
{
strerror_r
(
errorNumber
,
buffer
,
sizeof
(
buffer
));
sysErrorArray
=
buffer
;
}
else
{
sysErrorArray
=
sysErrorString
;
}
}
#endif
...
...
@@ -250,6 +298,7 @@ static String makeDescriptionImpl(DescriptionStyle style, const char* code, int
pos
=
_
::
fill
(
pos
,
codeArray
,
colon
,
sysErrorArray
);
break
;
}
for
(
size_t
i
=
0
;
i
<
argValues
.
size
();
i
++
)
{
if
(
i
>
0
||
style
!=
LOG
)
{
pos
=
_
::
fill
(
pos
,
delim
);
...
...
@@ -269,7 +318,7 @@ static String makeDescriptionImpl(DescriptionStyle style, const char* code, int
void
Debug
::
logInternal
(
const
char
*
file
,
int
line
,
LogSeverity
severity
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
getExceptionCallback
().
logMessage
(
severity
,
trimSourceFilename
(
file
).
cStr
(),
line
,
0
,
makeDescriptionImpl
(
LOG
,
nullptr
,
0
,
macroArgs
,
argValues
));
makeDescriptionImpl
(
LOG
,
nullptr
,
0
,
nullptr
,
macroArgs
,
argValues
));
}
Debug
::
Fault
::~
Fault
()
noexcept
(
false
)
{
...
...
@@ -292,18 +341,46 @@ void Debug::Fault::init(
const
char
*
file
,
int
line
,
Exception
::
Type
type
,
const
char
*
condition
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
exception
=
new
Exception
(
type
,
file
,
line
,
makeDescriptionImpl
(
ASSERTION
,
condition
,
0
,
macroArgs
,
argValues
));
makeDescriptionImpl
(
ASSERTION
,
condition
,
0
,
nullptr
,
macroArgs
,
argValues
));
}
void
Debug
::
Fault
::
init
(
const
char
*
file
,
int
line
,
int
osErrorNumber
,
const
char
*
condition
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
exception
=
new
Exception
(
typeOfErrno
(
osErrorNumber
),
file
,
line
,
makeDescriptionImpl
(
SYSCALL
,
condition
,
osErrorNumber
,
macroArgs
,
argValues
));
makeDescriptionImpl
(
SYSCALL
,
condition
,
osErrorNumber
,
nullptr
,
macroArgs
,
argValues
));
}
#if _WIN32
void
Debug
::
Fault
::
init
(
const
char
*
file
,
int
line
,
Win32Error
osErrorNumber
,
const
char
*
condition
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
LPVOID
ptr
;
// TODO(now): Use FormatMessageW() instead.
// TODO(now): Why doesn't this work for winsock errors?
DWORD
result
=
FormatMessageA
(
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
FORMAT_MESSAGE_FROM_SYSTEM
|
FORMAT_MESSAGE_IGNORE_INSERTS
,
NULL
,
osErrorNumber
.
number
,
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_DEFAULT
),
(
LPTSTR
)
&
ptr
,
0
,
NULL
);
if
(
result
>
0
)
{
KJ_DEFER
(
LocalFree
(
ptr
));
exception
=
new
Exception
(
typeOfWin32Error
(
osErrorNumber
.
number
),
file
,
line
,
makeDescriptionImpl
(
SYSCALL
,
condition
,
0
,
reinterpret_cast
<
char
*>
(
ptr
),
macroArgs
,
argValues
));
}
else
{
auto
message
=
kj
::
str
(
"win32 error code: "
,
osErrorNumber
.
number
);
exception
=
new
Exception
(
typeOfWin32Error
(
osErrorNumber
.
number
),
file
,
line
,
makeDescriptionImpl
(
SYSCALL
,
condition
,
0
,
message
.
cStr
(),
macroArgs
,
argValues
));
}
}
#endif
String
Debug
::
makeDescriptionInternal
(
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
return
makeDescriptionImpl
(
LOG
,
nullptr
,
0
,
macroArgs
,
argValues
);
return
makeDescriptionImpl
(
LOG
,
nullptr
,
0
,
nullptr
,
macroArgs
,
argValues
);
}
int
Debug
::
getOsErrorNumber
(
bool
nonblocking
)
{
...
...
@@ -316,6 +393,12 @@ int Debug::getOsErrorNumber(bool nonblocking) {
:
result
;
}
#if _WIN32
Debug
::
Win32Error
Debug
::
getWin32Error
()
{
return
Win32Error
(
::
GetLastError
());
}
#endif
Debug
::
Context
::
Context
()
:
logged
(
false
)
{}
Debug
::
Context
::~
Context
()
noexcept
(
false
)
{}
...
...
c++/src/kj/debug.h
View file @
c02dce53
...
...
@@ -165,6 +165,24 @@ namespace kj {
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \
errorNumber, code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal())
#if _WIN32
#define KJ_WIN32(call, ...) \
if (::kj::_::Debug::isWin32Success(call)) {} else \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \
::kj::_::Debug::getWin32Error(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal())
#define KJ_WINSOCK(call, ...) \
if ((call) != SOCKET_ERROR) {} else \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \
::kj::_::Debug::getWin32Error(), #call, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal())
#define KJ_FAIL_WIN32(code, errorNumber, ...) \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \
::kj::_::Debug::Win32Error(errorNumber), code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal())
#endif
#define KJ_UNIMPLEMENTED(...) \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \
nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal())
...
...
@@ -223,6 +241,24 @@ namespace kj {
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \
errorNumber, code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal())
#if _WIN32
#define KJ_WIN32(call, ...) \
if (::kj::_::Debug::isWin32Success(call)) {} else \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \
::kj::_::Debug::getWin32Error(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal())
#define KJ_WINSOCK(call, ...) \
if ((call) != SOCKET_ERROR) {} else \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \
::kj::_::Debug::getWin32Error(), #call, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal())
#define KJ_FAIL_WIN32(code, errorNumber, ...) \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \
::kj::_::Debug::Win32Error(errorNumber), code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal())
#endif
#define KJ_UNIMPLEMENTED(...) \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \
nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal())
...
...
@@ -275,6 +311,14 @@ public:
typedef
LogSeverity
Severity
;
// backwards-compatibility
#if _WIN32
struct
Win32Error
{
// Hack for overloading purposes.
uint
number
;
inline
explicit
Win32Error
(
uint
number
)
:
number
(
number
)
{}
};
#endif
static
inline
bool
shouldLog
(
LogSeverity
severity
)
{
return
severity
>=
minSeverity
;
}
// Returns whether messages of the given severity should be logged.
...
...
@@ -289,16 +333,17 @@ public:
class
Fault
{
public
:
template
<
typename
...
Params
>
Fault
(
const
char
*
file
,
int
line
,
Exception
::
Type
type
,
const
char
*
condition
,
const
char
*
macroArgs
,
Params
&&
...
params
);
template
<
typename
...
Params
>
Fault
(
const
char
*
file
,
int
line
,
int
osErrorNumber
,
template
<
typename
Code
,
typename
...
Params
>
Fault
(
const
char
*
file
,
int
line
,
Code
code
,
const
char
*
condition
,
const
char
*
macroArgs
,
Params
&&
...
params
);
Fault
(
const
char
*
file
,
int
line
,
Exception
::
Type
type
,
const
char
*
condition
,
const
char
*
macroArgs
);
Fault
(
const
char
*
file
,
int
line
,
int
osErrorNumber
,
const
char
*
condition
,
const
char
*
macroArgs
);
#if _WIN32
Fault
(
const
char
*
file
,
int
line
,
Win32Error
osErrorNumber
,
const
char
*
condition
,
const
char
*
macroArgs
);
#endif
~
Fault
()
noexcept
(
false
);
KJ_NOINLINE
KJ_NORETURN
(
void
fatal
());
...
...
@@ -309,6 +354,10 @@ public:
const
char
*
condition
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
);
void
init
(
const
char
*
file
,
int
line
,
int
osErrorNumber
,
const
char
*
condition
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
);
#if _WIN32
void
init
(
const
char
*
file
,
int
line
,
Win32Error
osErrorNumber
,
const
char
*
condition
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
);
#endif
Exception
*
exception
;
};
...
...
@@ -326,6 +375,12 @@ public:
template
<
typename
Call
>
static
SyscallResult
syscall
(
Call
&&
call
,
bool
nonblocking
);
#if _WIN32
static
bool
isWin32Success
(
int
boolean
);
static
bool
isWin32Success
(
void
*
handle
);
static
Win32Error
getWin32Error
();
#endif
class
Context
:
public
ExceptionCallback
{
public
:
Context
();
...
...
@@ -394,21 +449,12 @@ inline void Debug::log<>(const char* file, int line, LogSeverity severity, const
logInternal
(
file
,
line
,
severity
,
macroArgs
,
nullptr
);
}
template
<
typename
...
Params
>
Debug
::
Fault
::
Fault
(
const
char
*
file
,
int
line
,
Exception
::
Type
typ
e
,
template
<
typename
Code
,
typename
...
Params
>
Debug
::
Fault
::
Fault
(
const
char
*
file
,
int
line
,
Code
cod
e
,
const
char
*
condition
,
const
char
*
macroArgs
,
Params
&&
...
params
)
:
exception
(
nullptr
)
{
String
argValues
[
sizeof
...(
Params
)]
=
{
str
(
params
)...};
init
(
file
,
line
,
type
,
condition
,
macroArgs
,
arrayPtr
(
argValues
,
sizeof
...(
Params
)));
}
template
<
typename
...
Params
>
Debug
::
Fault
::
Fault
(
const
char
*
file
,
int
line
,
int
osErrorNumber
,
const
char
*
condition
,
const
char
*
macroArgs
,
Params
&&
...
params
)
:
exception
(
nullptr
)
{
String
argValues
[
sizeof
...(
Params
)]
=
{
str
(
params
)...};
init
(
file
,
line
,
osErrorNumber
,
condition
,
macroArgs
,
init
(
file
,
line
,
code
,
condition
,
macroArgs
,
arrayPtr
(
argValues
,
sizeof
...(
Params
)));
}
...
...
@@ -424,6 +470,22 @@ inline Debug::Fault::Fault(const char* file, int line, kj::Exception::Type type,
init
(
file
,
line
,
type
,
condition
,
macroArgs
,
nullptr
);
}
#if _WIN32
inline
Debug
::
Fault
::
Fault
(
const
char
*
file
,
int
line
,
Win32Error
osErrorNumber
,
const
char
*
condition
,
const
char
*
macroArgs
)
:
exception
(
nullptr
)
{
init
(
file
,
line
,
osErrorNumber
,
condition
,
macroArgs
,
nullptr
);
}
inline
bool
Debug
::
isWin32Success
(
int
boolean
)
{
return
boolean
;
}
inline
bool
Debug
::
isWin32Success
(
void
*
handle
)
{
// Assume null and INVALID_HANDLE_VALUE mean failure.
return
handle
!=
nullptr
&&
handle
!=
(
void
*
)
-
1
;
}
#endif
template
<
typename
Call
>
Debug
::
SyscallResult
Debug
::
syscall
(
Call
&&
call
,
bool
nonblocking
)
{
while
(
call
()
<
0
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment