Fabric Crashlytics is crashing on calling CLSLogv method occasionally. The crash is very random, not sure on what input it's crashing.
Here is the crash log:
Crashed: com.apple.main-thread
0 CoreFoundation 0x18289d688 __CFStringAppendFormatCore + 12780
1 CoreFoundation 0x18289a464 _CFStringCreateWithFormatAndArgumentsAux2 + 244
2 Foundation 0x1831b6320 -[NSPlaceholderString initWithFormat:locale:arguments:] + 168
3 Dream11 0x1004823e4 CLSLogv (CLSUserLogging.m:368)
4 Dream11 0x1001d73a8 specialized crashlyticsLog(format : String, [CVarArg], file : String, function : String, line : Int) -> () (LogManager.swift)`
Here is the method.
func VERBOSELOG(_ format: String = "",
_ args:[CVarArg] = [],
file: String = #file,
function: String = #function,
line: Int = #line) {
if ENABLED_LOGGING.contains("VERBOSE") {
do {
try crashlyticsLog(format: "\nVERBOSE: " + format, args, file: file, function: function, line: line)
} catch let error {
print(error)
}
}
}
func crashlyticsLog(format: String = "",
_ args:[CVarArg] = [],
file: String = #file,
function: String = #function,
line: Int = #line) throws {
let filename = file.components(separatedBy: "/").last!.components(separatedBy: ".").first!
#if SWIFT_DEBUG
print("\(filename).\(function) line \(line) $ \(format)")
#else
CLSLogv("\(filename).\(function) line \(line) $ \(format)", getVaList(args))
#endif
}
I faced a similar crash, that happened randomly with following stack trace
0 CoreFoundation 0x1b99b84d4 __CFStringAppendFormatCore + 6000
1 CoreFoundation 0x1b99ba5bc _CFStringCreateWithFormatAndArgumentsAux2 + 136
2 flockmail 0x1006725ec CLSLogv + 374 (CLSUserLogging.m:374)
The problem that I later figured out was the way I was logging messages.
CLSLogv(message, getVaList([])) // Incorrect
I was passing message in the format, so if the message had some %#'s or %d's or %0 or similar stuff, then it would look for vaList to replace it.
Fix was
CLSLogv("%#", getVaList([message]))
In you case, it seems format is supplied from outside, just make sure the format string parameter is in sync with args parameter.
Further references :
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/FormatStrings.html
https://docs.fabric.io/apple/crashlytics/enhanced-reports.html#custom-logs
Is it the character limit of NSLog, I had the same crash for NSLog and CLSLogv. Not for print
Related
yesterday I updated my Vue project to the latest Bootstrap version (5.2) and now I have a SASS Error while starting.
ERROR Failed to compile with 1 error 10:45:42
error in ./src/assets/scss/config/modern/app.scss
Syntax Error: SassError: argument `$color` of `red($color)` must be a color
on line 185 of node_modules/bootstrap/scss/_functions.scss, in function `red`
from line 185 of node_modules/bootstrap/scss/_functions.scss, in function `luminance`
from line 174 of node_modules/bootstrap/scss/_functions.scss, in function `contrast-ratio`
from line 159 of node_modules/bootstrap/scss/_functions.scss, in function `color-contrast`
from line 7 of node_modules/bootstrap/scss/_accordion.scss
from line 29 of node_modules/bootstrap/scss/bootstrap.scss
from line 15 of src/assets/scss/config/modern/bootstrap.scss
from line 19 of src/assets/scss/config/modern/app.scss
>> "r": red($color),
It's about this code snippet:
// File: _functions.scss
// Return WCAG2.1 relative luminance
// See https://www.w3.org/TR/WCAG/#dfn-relative-luminance
// See https://www.w3.org/TR/WCAG/#dfn-contrast-ratio
#function luminance($color) {
$rgb: (
"r": red($color),
"g": green($color),
"b": blue($color)
);
#each $name, $value in $rgb {
$value: if(divide($value, 255) < .03928, divide(divide($value, 255), 12.92), nth($_luminance-list, $value + 1));
$rgb: map-merge($rgb, ($name: $value));
}
#return (map-get($rgb, "r") * .2126) + (map-get($rgb, "g") * .7152) + (map-get($rgb, "b") * .0722);
}
And that's the trigger:
// File: _accordion.scss
// scss-docs-start accordion-css-vars
--#{$prefix}accordion-color: #{color-contrast($accordion-bg)};
I know, the error says, the function gets a wrong parameter, which is not of type color, but I never user it my self.
How can I fix this error and why does it occur?
I’m implementing Apple Sign In in React Native using this library:
https://github.com/invertase/react-native-apple-authentication
And there’s a handler for the onPress event of the Apple Sign-In button given like so:
import { appleAuth } from '#invertase/react-native-apple-authentication';
async function onAppleButtonPress() {
// performs login request
const appleAuthRequestResponse = await appleAuth.performRequest({
requestedOperation: appleAuth.Operation.LOGIN,
requestedScopes: [appleAuth.Scope.EMAIL, appleAuth.Scope.FULL_NAME],
});
// get current authentication state for user
// /!\ This method must be tested on a real device. On the iOS simulator it always throws an error.
const credentialState = await appleAuth.getCredentialStateForUser(appleAuthRequestResponse.user);
// use credentialState response to ensure the user is authenticated
if (credentialState === appleAuth.State.AUTHORIZED) {
// user is authenticated
}
}
However, when I convert this to clojurescript like so:
(reg-fx
:apple-signin-fx
(fn [navigation]
(go (let [appleAuthRequestResponse
(<p! (.performRequest appleAuth
(clj->js
{:requestedOperation (.. appleAuth -Operation -LOGIN)
:requestedScopes [(.. appleAuth -Scope -Email)
(.. appleAuth -Scope -FULL_NAME)]})))]))))
I’m getting the following error:
JSON value '{
nonceEnabled = 1;
requestedOperation = 1;
requestedScopes = (
"<null>",
1
);
}' of type NSMutableDictionary cannot be converted to ASAuthorizationAppleIDRequest *
+[RCTConvert(ASAuthorizationAppleIDRequest) ASAuthorizationAppleIDRequest:]
RCTConvert+ASAuthorizationAppleIDRequest.m:85
__41-[RCTModuleMethod processMethodSignature]_block_invoke_16
-[RCTModuleMethod invokeWithBridge:module:arguments:]
facebook::react::invokeInner(RCTBridge*, RCTModuleData*, unsigned int, folly::dynamic const&)
facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int)::$_0::operator()() const
invocation function for block in facebook::react::RCTNativeModule::invoke(unsigned int, folly::dynamic&&, int)
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_main_queue_callback_4CF
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
-[UIApplication _run]
UIApplicationMain
main
start
How to fix this?
In objective-c, function cal is translated to objc_msgSend. e.g.
[foo doSomething:#"keke"]
is translated to
objc_msgSend(foo, "doSomething:", #"keke")
How could I step directly to foo.doSomething: while debugging in lldb?
lldb does provide thread plan which could control the step logic.
class GotoUser:
def __init__ (self, thread_plan, dict):
self.start_time = time.time()
self.thread_plan = thread_plan
target = self.thread_plan.GetThread().GetProcess().GetTarget();
module = target.GetModuleAtIndex(0)
sbaddr = lldb.SBAddress(module.GetObjectFileHeaderAddress())
self.start_address = sbaddr.GetLoadAddress(target)
module = target.GetModuleAtIndex(1)
sbaddr = lldb.SBAddress(module.GetObjectFileHeaderAddress())
self.end_address = sbaddr.GetLoadAddress(target)
print "start addr: ", hex(self.start_address), " end addr: ", hex(self.end_address)
def explains_stop (self, event):
if self.thread_plan.GetThread().GetStopReason()== lldb.eStopReasonTrace:
return True
else:
return False
def should_stop (self, event):
cur_pc = self.thread_plan.GetThread().GetFrameAtIndex(0).GetPC()
if cur_pc >= self.start_address and cur_pc <= self.end_address:
self.thread_plan.SetPlanComplete(True)
print 'time used ', (time.time() - self.start_time)
return True
else:
return False
def should_step (self):
return True
create a python script, load it to lldb.
run thread step-scripted gotouser.GotoUser.
mission completed.
full source code:
https://github.com/Jichao/lldb-scripts/blob/master/gotouser.py
version built into lldb:
https://github.com/Jichao/lldb
Using the Python thread plan is clever! But you should not have to do this for ObjC messages. lldb knows that objc_msgSend & a few others are the dispatch functions for ObjC messages. So if a step in ends up at objc_msgSend, lldb will figure out the method implementation from the object/selector pair passed in, set a breakpoint there, and continue.
For instance:
(lldb) run
Process 55502 launched: '/private/tmp/trivial' (x86_64)
Process 55502 stopped
* thread #1: tid = 0x32619ba, function: main , stop reason = breakpoint 1.1
frame #0: 0x0000000100000f28 trivial`main at trivial.m:18
15 main()
16 {
17 Trivial *my_foo = [[Trivial alloc] init];
-> 18 [my_foo doSomething];
19 return 0;
20 }
(lldb) s
Process 55502 stopped
* thread #1: tid = 0x32619ba, function: -[Trivial doSomething] , stop reason = step in
frame #0: 0x0000000100000ed7 trivial`-[Trivial doSomething] at trivial.m:10
7 #implementation Trivial
8 - (void) doSomething
9 {
-> 10 NSLog(#"%# called doSomething.", self);
11 }
12 #end
13
So the step in stopped at the actual message receiver in this case. If that is not what is happening for you, most likely something is fooling the part of lldb that does the object/selector -> implementation lookup. I'd have to know more about your code to figure out why that might be.
How could I step directly to foo.doSomething: while debugging in lldb?
seems: No possbile
Workaround: add related breakpoint
your here: -[foo doSomething:]
I'm very new to ANTLR4 and am trying to build my own language. So my grammar starts at
program: <EOF> | statement | functionDef | statement program | functionDef program;
and my statement is
statement: selectionStatement | compoundStatement | ...;
and
selectionStatement
: If LeftParen expression RightParen compoundStatement (Else compoundStatement)?
| Switch LeftParen expression RightParen compoundStatement
;
compoundStatement
: LeftBrace statement* RightBrace;
Now the problem is, that when I test a piece of code against selectionStatement or statement it passes the test, but when I test it against program it fails to recognize. Can anyone help me on this? Thank you very much
edit: the code I use to test is the following:
if (x == 2) {}
It passes the test against selectionStatement and statement but fails at program. It appears that program only accepts if...else
if (x == 2) {} else {}
Edit 2:
The error message I received was
<unknown>: Incorrect error: no viable alternative at input 'if(x==2){}'
Cannot answer your question given the incomplete information provided: the statement rule is partial and the compoundStatement rule is missing.
Nonetheless, there are two techniques you should be using to answer this kind of question yourself (in addition to unit tests).
First, ensure that the lexer is working as expected. This answer shows how to dump the token stream directly.
Second, use a custom ErrorListener to provide a meaningful/detailed description of its parse path to every encountered error. An example:
public class JavaErrorListener extends BaseErrorListener {
public int lastError = -1;
#Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
String msg, RecognitionException e) {
Parser parser = (Parser) recognizer;
String name = parser.getSourceName();
TokenStream tokens = parser.getInputStream();
Token offSymbol = (Token) offendingSymbol;
int thisError = offSymbol.getTokenIndex();
if (offSymbol.getType() == -1 && thisError == tokens.size() - 1) {
Log.debug(this, name + ": Incorrect error: " + msg);
return;
}
String offSymName = JavaLexer.VOCABULARY.getSymbolicName(offSymbol.getType());
List<String> stack = parser.getRuleInvocationStack();
// Collections.reverse(stack);
Log.error(this, name);
Log.error(this, "Rule stack: " + stack);
Log.error(this, "At line " + line + ":" + charPositionInLine + " at " + offSymName + ": " + msg);
if (thisError > lastError + 10) {
lastError = thisError - 10;
}
for (int idx = lastError + 1; idx <= thisError; idx++) {
Token token = tokens.get(idx);
if (token.getChannel() != Token.HIDDEN_CHANNEL) Log.error(this, token.toString());
}
lastError = thisError;
}
}
Note: adjust the Log statements to whatever logging package you are using.
Finally, Antlr doesn't do 'weird' things - just things that you don't understand.
It's normally easy to log all messages sent to a class with DTrace, for example by using trace_msg_send.sh script from here:
#!/usr/sbin/dtrace -s
#pragma D option quiet
unsigned long long indention;
int indentation_amount;
BEGIN {
indentation_amount = 4;
}
objc$target:$1::entry
{
method = (string)&probefunc[1];
type = probefunc[0];
class = probemod;
printf("%*s%s %c[%s %s]\n", indention * indentation_amount, "", "->", type, class, method);
indention++;
}
objc$target:$1::return
{
indention--;
method = (string)&probefunc[1];
type = probefunc[0];
class = probemod;
printf("%*s%s %c[%s %s]\n", indention * indentation_amount, "", "<-", type, class, method);
}
Given the code:
$ cat > test.m
#include <stdio.h>
#import <Foundation/Foundation.h>
#interface TestClass : NSObject
+ (int)randomNum;
#end
#implementation TestClass
+ (int)randomNum {
return 4; // chosen by fair dice roll.
// guaranteed to be random.
}
#end
int main(void) {
printf("num: %d\n", [TestClass randomNum]);
return 0;
}
^D
you would get the following output by using the DTrace script:
$ gcc test.m -lobjc -o test
$ ./test
num: 4
$ sudo ./trace_msg_send.d -c ./test TestClass
num: 4
-> +[TestClass randomNum]
<- +[TestClass randomNum]
However if we strip the binary:
$ strip test
$ sudo ./trace_msg_send.d -c ./test TestClass
dtrace: failed to compile script ./trace_msg_send.d: line 11: probe description objc49043:TestClass::entry does not match any probes
the script no longer works.
Is there a way of telling DTrace, where the stripped classes/message implementations are located?
Maybe using the info available from class-dump, like in the answer for Import class-dump info into GDB.
I have created a script that tries to compare the classname at runtime, however it doesn't seem to work:
#!/usr/sbin/dtrace -s
#pragma D option quiet
unsigned long long indention;
int indentation_amount;
BEGIN {
indentation_amount = 4;
}
objc$target:::entry
{
// Assumes 64 bit executable
isaptr = *(uint64_t *)copyin(arg0, 8);
class_rw = *(uint64_t *)copyin(isaptr + 4*8, 8);
class_ro = *(uint64_t *)copyin(class_rw + 8, 8);
classnameptr = *(uint64_t *)copyin(class_ro + 4*4 + 8, 8);
classname = copyinstr(classnameptr);
type = classname == $$1? (string)&probefunc[0]: "";
method = classname == $$1? (string)&probefunc[1]: "";
arrow = classname == $$1? "->": "";
space = classname == $$1? " ": "";
bracket1 = classname == $$1? "[": "";
bracket2 = classname == $$1? "]": "";
current_indention = classname == $$1? indention: 0;
indention = classname == $$1? indention + 1: indention;
newline = classname == $$1? "\n": "";
classname = classname == $$1? classname: "";
printf("%*s%s%s%.1s%s%s%s%s%s%s", current_indention * indentation_amount, "", arrow, space, type, bracket1, classname, space, method, bracket2, newline);
}
Running sudo ./trace_msg_send2.d -c ./test TestClass prints:
num: 4
dtrace: error on enabled probe ID 179 (ID 13922: objc3517:NSObject:+load:entry): invalid address (0x7fff8204e03e) in action #5 at DIF offset 12
dtrace: error on enabled probe ID 186 (ID 13915: objc3517:__IncompleteProtocol:+load:entry): invalid address (0x7fff8204e01f) in action #5 at DIF offset 12
dtrace: error on enabled probe ID 195 (ID 13906: objc3517:Protocol:+load:entry): invalid address (0x7fff8204e034) in action #5 at DIF offset 12
-> +[TestClass initialize]
where -> -[TestClass randomNum:] is missing.