I am trying to make a game with flutter's library Flame. But I am getting this error every time. It is saying that the update is called on null. But I have initialized in the initialize function. I have tried several ways but nothing seems to work. Please help me fix the bug.
import 'dart:math';
import 'dart:ui';
import 'package:flame/flame.dart';
import 'package:flame/game.dart';
import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:small_game/components/Enemy.dart';
import 'package:small_game/components/enemy_spawner.dart';
import 'package:small_game/components/heath_bar.dart';
import 'package:small_game/components/highscoreText.dart';
import 'package:small_game/components/player.dart';
import 'package:small_game/components/score_text.dart';
import 'package:small_game/components/startText.dart';
import 'package:small_game/states.dart' as gameState;
class GameController extends Game{
Random rand;
Size screenSize;
double tileSize;
Player player;
EnemySpawner enemySpawner;
List<Enemy> enemies;
HealthBar healthBar;
int score;
ScoreText scoreText;
SharedPreferences storage;
gameState.State state;
HighScoreText highScoreText;
StartText startText;
GameController(this.storage){
initialize();
}
void initialize() async{
rand = Random();
resize(await Flame.util.initialDimensions());
player = Player(this);
state = gameState.State.menu;
enemies = List<Enemy>();
enemySpawner = EnemySpawner(this);
healthBar = HealthBar(this);
score = 0;
highScoreText = HighScoreText(this);
startText = StartText(this);
}
#override
void render(Canvas canvas) {
Rect background = Rect.fromLTWH(0, 0, screenSize.width, screenSize.height);
Paint backgroundPaint = Paint()..color = Color(0xffFCFCFA);
canvas.drawRect(background, backgroundPaint);
player.render(canvas);
if(state == gameState.State.menu){
startText.render(canvas);
highScoreText.render(canvas);
} else if(state == gameState.State.playing) {
enemies.forEach((Enemy enemy) => enemy.render(canvas));
scoreText.render(canvas);
healthBar.render(canvas);
}
}
#override
void update(double t) {
if(state == gameState.State.menu){
highScoreText.update(t);
startText.update(t);
} else if(state == gameState.State.playing) {
enemies.forEach((Enemy enemy) => enemy.update(t));
enemies.removeWhere((Enemy enemy) => enemy.isDead);
player.update(t);
scoreText.update(t);
healthBar.update(t);
enemySpawner.update(t);
}
}
void resize(Size size){
screenSize = size;
tileSize = screenSize.width / 10;
}
void onTapDown(TapDownDetails d){
enemies.forEach((Enemy enemy) {
if(state == gameState.State.menu){
state = gameState.State.playing;
}
if(enemy.enemyRect.contains(d.globalPosition)){
enemy.onTapDown();
}
});
}
void spawnEnemies(){
double x,y;
switch(rand.nextInt(4)){
case 0:
//TOP
x = rand.nextDouble() * screenSize.width;
y = -tileSize * 2.5;
break;
case 1:
//RIGHT
x = (tileSize * 2.5) + screenSize.width;
y = rand.nextDouble() * screenSize.height;
break;
case 2:
//BOTTOM
x = rand.nextDouble() * screenSize.width;
y = (tileSize * 2.5) + screenSize.height;
break;
case 3:
//LEFT
x = -(tileSize * 2.5);
y = rand.nextDouble() * screenSize.height;
}
enemies.add(Enemy(this, x, y));
}
}
My error:
I/flutter (20131): ══╡ EXCEPTION CAUGHT BY SCHEDULER LIBRARY
╞═════════════════════════════════════════════════════════ I/flutter
(20131): The following NoSuchMethodError was thrown during a scheduler
callback: I/flutter (20131): The method 'update' was called on null.
I/flutter (20131): Receiver: null I/flutter (20131): Tried calling:
update(0.0) I/flutter (20131): I/flutter (20131): When the exception
was thrown, this was the stack: I/flutter (20131): #0
Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
I/flutter (20131): #1 GameController.update (package:small_game/gameController.dart:69:17)
I/flutter (20131): #2 GameRenderBox._update (package:flame/game.dart:360:10)
I/flutter (20131): #3 GameRenderBox._tick (package:flame/game.dart:353:5)
I/flutter (20131): #4 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1033:15)
I/flutter (20131): #5 SchedulerBinding.handleBeginFrame.
(package:flutter/src/scheduler/binding.dart:951:11)
I/flutter (20131): #6 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377:8)
I/flutter (20131): #7 SchedulerBinding.handleBeginFrame (package:flutter/src/scheduler/binding.dart:949:17)
I/flutter (20131): #8 SchedulerBinding.scheduleWarmUpFrame.
(package:flutter/src/scheduler/binding.dart:780:7)
I/flutter (20131): #17 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:382:19)
I/flutter (20131): #18 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5)
I/flutter (20131): #19 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:172:12)
I/flutter (20131): (elided 8 frames from package dart:async and package dart:async-patch)
I/flutter (20131):
I/flutter (20131):
I/flutter (20131): This exception was thrown in the context of a scheduler callback. When the scheduler callback was registered (as
opposed to when the exception was thrown), this was the stack:
I/flutter (20131): #0 new _FrameCallbackEntry. (package:flutter/src/scheduler/binding.dart:112:33)
I/flutter (20131): #1 new _FrameCallbackEntry (package:flutter/src/scheduler/binding.dart:115:6)
I/flutter (20131): #2 SchedulerBinding.scheduleFrameCallback (package:flutter/src/scheduler/binding.dart:459:49)
I/flutter (20131): #3 GameRenderBox._scheduleTick (package:flame/game.dart:341:50)
I/flutter (20131): #4 GameRenderBox.attach (package:flame/game.dart:328:5)
I/flutter (20131): #5 RenderObjectWithChildMixin.attach (package:flutter/src/rendering/object.dart:2886:14)
I/flutter (20131): #6 AbstractNode.adoptChild (package:flutter/src/foundation/node.dart:132:13)
I/flutter (20131): #7 RenderObject.adoptChild (package:flutter/src/rendering/object.dart:1232:11)
I/flutter (20131): #8 RenderObjectWithChildMixin.child= (package:flutter/src/rendering/object.dart:2879:7)
I/flutter (20131): #9 RenderObjectToWidgetElement.insertChildRenderObject
(package:flutter/src/widgets/binding.dart:1020:18)
I/flutter (20131): #10 RenderObjectElement.attachRenderObject (package:flutter/src/widgets/framework.dart:4986:35)
I/flutter (20131): #11 RenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4752:5)
I/flutter (20131): #12 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3101:14)
I/flutter (20131): #13 Element.updateChild (package:flutter/src/widgets/framework.dart:2904:12)
I/flutter (20131): #14 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3961:16)
I/flutter (20131): #15 Element.rebuild (package:flutter/src/widgets/framework.dart:3738:5)
I/flutter (20131): #16 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3924:5)
I/flutter (20131): #17 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3919:5)
I/flutter (20131): #18 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3101:14)
I/flutter (20131): #19 Element.updateChild (package:flutter/src/widgets/framework.dart:2904:12)
I/flutter (20131): #20 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:998:16)
I/flutter (20131): #21 RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:969:5)
I/flutter (20131): #22 RenderObjectToWidgetAdapter.attachToRenderTree.
(package:flutter/src/widgets/binding.dart:915:17)
I/flutter (20131): #23 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2328:19)
I/flutter (20131): #24 RenderObjectToWidgetAdapter.attachToRenderTree
(package:flutter/src/widgets/binding.dart:914:13)
I/flutter (20131): #25 WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:795:7)
I/flutter (20131): #26 runApp (package:flutter/src/widgets/binding.dart:845:7)
I/flutter (20131): #27 main (package:small_game/main.dart:17:3)
I/flutter (20131): (elided 14 frames from package dart:async and package dart:async-patch)
Your initialize function is async, meaning it will run in the background. Therefore when update is first called, startText is null and gives you the NPE. You probably want to add some check on update to make sure it's initialized before moving forward with update code, or make initialize sync and then do whatever async stuff you need later (since initializing startText is certainly not one of them).
Related
I have a crash in SLL_Next in a setter of an attribute of type vector<pair<int,enum>>
void setA(const vector<pair<int,enum>>& A){_A = A;} // A.size() = 1
class B {
vector<pair<int,enum>> _A {};
public:
void setA(const vector<pair<int,enum>>& A){_A = A;}
};
int main(){
.
.
.
vector<pair<int,enum>> A;
.
.
.
A.push_back(element);
.
.
.
setA(A);// get segfault in SLL_Next
.
.
.
}
Back trace :
Thread 1 "a" received signal SIGSEGV, Segmentation fault.
tcmalloc::SLL_TryPop (rv=<synthetic pointer>, list=0x790f060) at src/linked_list.h:69
69 void *next = SLL_Next(*list);
(gdb) bt
#0 tcmalloc::SLL_TryPop (rv=<synthetic pointer>, list=0x790f060) at src/linked_list.h:69
#1 tcmalloc::ThreadCache::FreeList::TryPop (rv=<synthetic pointer>, this=0x790f060) at src/thread_cache.h:220
#2 tcmalloc::ThreadCache::Allocate (oom_handler=0x7ffff78c5300 <tcmalloc::cpp_throw_oom(unsigned long)>, cl=1, size=8, this=<optimized out>) at src/thread_cache.h:379
#3 malloc_fast_path<tcmalloc::cpp_throw_oom> (size=8) at src/tcmalloc.cc:1874
#4 tc_new (size=8) at src/tcmalloc.cc:1995
#5 0x0000000000506e50 in __gnu_cxx::new_allocator<std::pair<int, enum> >::allocate (this=0x114aedc8, __n=1) at /u/tools/gnu/gcc/os3fp/gcc-6.2.0/include/c++/6.2.0/ext/new_allocator.h:104
#6 0x000000000050334b in std::allocator_traits<std::allocator<std::pair<int, enum> > >::allocate (__a=..., __n=1) at /u/tools/gnu/gcc/os3fp/gcc-6.2.0/include/c++/6.2.0/bits/alloc_traits.h:416
#7 0x00000000004fd3b2 in std::_Vector_base<std::pair<int, enum>, std::allocator<std::pair<int, enum> > >::_M_allocate (this=0x114aedc8, __n=1) at /u/tools/gnu/gcc/os3fp/gcc-6.2.0/include/c++/6.2.0/bits/stl_vector.h:170
#8 0x00000000004f9a92 in std::vector<std::pair<int, enum>, std::allocator<std::pair<int, enum> > >::_M_allocate_and_copy<__gnu_cxx::__normal_iterator<std::pair<int, enum> const*, std::vector<std::pair<int, enum>, std::allocator<std::pair<int, enum> > > > > (this=0x114aedc8, __n=1, __first=..., __last=...)
at /u/tools/gnu/gcc/os3fp/gcc-6.2.0/include/c++/6.2.0/bits/stl_vector.h:1222
#9 0x00000000004f70fc in std::vector<std::pair<int, enum>, std::allocator<std::pair<int, enum> > >::operator= (this=0x114aedc8, __x=...) at /u/tools/gnu/gcc/os3fp/gcc-6.2.0/include/c++/6.2.0/bits/vector.tcc:195
#10 0x00000000004f616e in B::setA (this=0x114aed20, A=...) at ~/WORK/B.h:110
I tried to do the following scenarios:
Scenario(1):
Clear the vector A just before doing setA(A)
Replace _A = A by _A.reserve(1) But I got the same segfault.
Code source became:
class B {
vector<pair<int,enum>> _A {};
public:
void setA(const vector<pair<int,enum>>& A){_A.reserve(1);}
};
int main(){
.
.
.
vector<pair<int,enum>> A;
.
.
.
A.clear();
setA(A);// get the same segfault in SLL_Next
.
.
.
}
Scenario(2)
Replace void setA(const vector<pair<int,enum>>& A){_A = A} by void setA(const vector<pair<int,enum>>& A){_A.reserve(2)}, the program pass this segfault and crashes in other different vector with the same segfault.
Scenario(3)
If I use a build without tcmalloc, the program will pass successfully.
Scenario(4)
If I change the type of _A from vector to set, the program passes this segfault and crashes with the same segfault in other vectors.
Does anyone have ever faced this kind of issue with using tcmalloc can please advise me on how to solve it?
I am new to flutter and developing a social media app. Every time I want to get data from firebase I got the error
QueryDocumentSnapshot has no instance method '[]'
Here's my code where I am getting the error
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:fluttershare/widgets/header.dart';
import 'package:fluttershare/widgets/progress.dart';
final usersRef = FirebaseFirestore.instance.collection('users');
class Timeline extends StatefulWidget {
#override
_TimelineState createState() => _TimelineState();
}
class _TimelineState extends State<Timeline> {
List<dynamic> users = [];
#override
void initState() {
// TODO: implement initState
getUsers();
//getUserById();
super.initState();
}
getUsers() async{
final QuerySnapshot snapshot = await usersRef.get();
setState(() {
users = snapshot.docs;
});
/*snapshot.docs.forEach((DocumentSnapshot doc){
print(doc.data());
print(doc.id);
print(doc.exists);
});*/
}
/*usersRef.get().then((QuerySnapshot snapshot){
snapshot.docs.forEach((DocumentSnapshot doc) {
print(doc.data());
});
});
}*/
/*getUserById() async{
final String id = "Hw75UQLfZPAZosI2O2Nu";
final DocumentSnapshot doc = await usersRef.doc(id).get();
print(doc.data());
print(doc.id);
print(doc.exists);
}*/
#override
Widget build(context) {
return Scaffold(
appBar: header(context, isAppTitle: true),
body: FutureBuilder(future: usersRef.get(),
builder: (context, snapshot) {
if (!snapshot.hasData){
return circularProgress();
}
final List<Text> children = snapshot.data.documents.map((doc) => Text(doc['username'])).toList();
return Container(
child: ListView(
children: children,
),
);
}
),
);
}
}
Error Log
Performing hot restart...
Syncing files to device sdk gphone x86 arm...
Restarted application in 706ms.
I/flutter ( 6385): User signed in!!!: GoogleSignInAccount:{displayName: Rinkumoni Khanikar, email: derekfrost621#gmail.com, id: 116999770966093637702, photoUrl: https://lh3.googleusercontent.com/a-/AOh14Gj1tc8cASVYMqeP-7NfiuWkfRQ5dnDHqNC2mhPNXA=s96-c}
I/flutter ( 6385): User signed in!!!: GoogleSignInAccount:{displayName: Rinkumoni Khanikar, email: derekfrost621#gmail.com, id: 116999770966093637702, photoUrl: https://lh3.googleusercontent.com/a-/AOh14Gj1tc8cASVYMqeP-7NfiuWkfRQ5dnDHqNC2mhPNXA=s96-c}
W/DynamiteModule( 6385): Local module descriptor class for providerinstaller not found.
I/DynamiteModule( 6385): Considering local module providerinstaller:0 and remote module providerinstaller:0
W/ProviderInstaller( 6385): Failed to load providerinstaller module: No acceptable module found. Local version is 0 and remote version is 0.
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building FutureBuilder<QuerySnapshot>(dirty, state:
_FutureBuilderState<QuerySnapshot>#a405e):
Class 'QueryDocumentSnapshot' has no instance method '[]'.
Receiver: Instance of 'QueryDocumentSnapshot'
Tried calling: []("username")
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 _TimelineState.build.<anonymous closure>.<anonymous closure> (package:fluttershare/pages/timeline.dart:57:82)
#2 MappedListIterable.elementAt (dart:_internal/iterable.dart:417:31)
#3 ListIterator.moveNext (dart:_internal/iterable.dart:343:26)
#4 new List.from (dart:core-patch/array_patch.dart:38:29)
#5 new List.of (dart:core-patch/array_patch.dart:68:17)
#6 ListIterable.toList (dart:_internal/iterable.dart:211:44)
#7 _TimelineState.build.<anonymous closure> (package:fluttershare/pages/timeline.dart:57:97)
#8 _FutureBuilderState.build (package:flutter/src/widgets/async.dart:740:55)
#9 StatefulElement.build (package:flutter/src/widgets/framework.dart:4663:28)
#10 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4546:15)
#11 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4719:11)
#12 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#13 StatefulElement.update (package:flutter/src/widgets/framework.dart:4751:5)
#14 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#15 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#16 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#17 StatelessElement.update (package:flutter/src/widgets/framework.dart:4627:5)
#18 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#19 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#20 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#21 ProxyElement.update (package:flutter/src/widgets/framework.dart:4906:5)
#22 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#23 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#24 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#25 ProxyElement.update (package:flutter/src/widgets/framework.dart:4906:5)
#26 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#27 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:5566:32)
#28 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6001:17)
#29 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#30 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#31 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4719:11)
#32 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#33 StatefulElement.update (package:flutter/src/widgets/framework.dart:4751:5)
#34 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#35 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#36 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#37 ProxyElement.update (package:flutter/src/widgets/framework.dart:4906:5)
#38 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#39 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#40 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4719:11)
#41 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#42 StatefulElement.update (package:flutter/src/widgets/framework.dart:4751:5)
#43 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#44 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:5881:14)
#45 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#46 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#47 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#48 StatelessElement.update (package:flutter/src/widgets/framework.dart:4627:5)
#49 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#50 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:5881:14)
#51 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#52 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#53 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4719:11)
#54 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#55 StatefulElement.update (package:flutter/src/widgets/framework.dart:4751:5)
#56 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#57 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#58 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4719:11)
#59 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#60 StatefulElement.update (package:flutter/src/widgets/framework.dart:4751:5)
#61 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#62 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#63 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#64 ProxyElement.update (package:flutter/src/widgets/framework.dart:4906:5)
#65 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#66 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#67 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#68 ProxyElement.update (package:flutter/src/widgets/framework.dart:4906:5)
#69 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#70 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#71 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4719:11)
#72 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#73 StatefulElement.update (package:flutter/src/widgets/framework.dart:4751:5)
#74 Element.updateChild (package:flutter/src/widgets/framework.dart:3245:15)
#75 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4571:16)
#76 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4719:11)
#77 Element.rebuild (package:flutter/src/widgets/framework.dart:4262:5)
#78 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2667:33)
#79 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:866:20)
#80 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:286:5)
#81 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1117:15)
#82 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1056:9)
#83 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:972:5)
#87 _invoke (dart:ui/hooks.dart:253:10)
#88 _drawFrame (dart:ui/hooks.dart:211:3)
(elided 3 frames from dart:async)
════════════════════════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building FutureBuilder<QuerySnapshot>(dirty, state: _FutureBuilderState<QuerySnapshot>#a405e):
Class 'QueryDocumentSnapshot' has no instance method '[]'.
Receiver: Instance of 'QueryDocumentSnapshot'
Tried calling: []("username")
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 _TimelineState.build.<anonymous closure>.<anonymous closure> (package:fluttershare/pages/timeline.dart:57:82)
#2 MappedListIterable.elementAt (dart:_internal/iterable.dart:417:31)
#3 ListIterator.moveNext (dart:_internal/iterable.dart:343:26)
#4 new List.from (dart:core-patch/array_patch.dart:38:29)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
Another exception was thrown: NoSuchMethodError: Class 'QueryDocumentSnapshot' has no instance method '[]'.
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building FutureBuilder<QuerySnapshot>(dirty, state: _FutureBuilderState<QuerySnapshot>#a405e):
Class 'QueryDocumentSnapshot' has no instance method '[]'.
Receiver: Instance of 'QueryDocumentSnapshot'
Tried calling: []("username")
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1 _TimelineState.build.<anonymous closure>.<anonymous closure> (package:fluttershare/pages/timeline.dart:57:82)
#2 MappedListIterable.elementAt (dart:_internal/iterable.dart:417:31)
#3 ListIterator.moveNext (dart:_internal/iterable.dart:343:26)
#4 new List.from (dart:core-patch/array_patch.dart:38:29)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
pubspec.yaml
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cloud_firestore: 0.14.0+2
image_picker: ^0.6.0+2
firebase_storage: 4.0.0
firebase_auth: 0.18.0+1
google_sign_in: ^4.0.1+1
geolocator: 6.0.0+4
uuid: ^2.0.0
image: ^2.0.7
animator: 2.0.1
cupertino_icons: 1.0.0
path_provider: 1.6.14
firebase_messaging: 7.0.0
timeago: 2.0.27
cached_network_image: 2.3.2+1
firebase_core: ^0.5.0
flutter_svg:
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
uses-material-design: true
fonts:
- family: Signatra
fonts:
- asset: assets/fonts/Signatra.ttf
assets:
- assets/images/google_signin_button.png
- assets/images/upload.svg
- assets/images/search.svg
- assets/images/activity_feed.svg
- assets/images/no_content.svg
main.dart
import 'package:flutter/material.dart';
import 'package:fluttershare/pages/home.dart';
import 'package:firebase_core/firebase_core.dart';
void main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FriendsHive',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.deepPurple,
accentColor: Colors.teal,
),
home: Home(),
);
}
}
Cloud Firestore
I know I have made some mistakes, please can anyone point out my mistakes.
Thank You!!!
Just a couple of stuff that needs fixing.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:fluttershare/widgets/header.dart';
import 'package:fluttershare/widgets/progress.dart';
final usersRef = FirebaseFirestore.instance.collection('users');
class Timeline extends StatefulWidget {
#override
_TimelineState createState() => _TimelineState();
}
class _TimelineState extends State<Timeline> {
/// What you're going to be getting back from your query is a QuerySnapshot, which will contain a List of DocumentSnapshots
Future<QuerySnapshot> querySnapshot;
#override
void initState() {
/// Here you set your querySnapshot to what you get from your database call
querySnapshot = getUsers();
super.initState();
}
Future<QuerySnapshot> getUsers() async {
return await usersRef.get();
}
#override
Widget build(context) {
return Scaffold(
appBar: header(context, isAppTitle: true),
body: FutureBuilder(
future: querySnapshot, // This is what you return in your future builder
builder: (context, snapshot) {
if ((snapshot.connectionState == ConnectionState.done) && (snapshot.hasData)){
List<dynamic> usernames = []; // This is where the usernames you get from Firebase will be saved
List<DocumentSnapshot> documentSnapshot = snapshot.documents; // Putting the snapshot into a List of DocumentSnapshot
for(DocumentSnapshot doc in documentSnapshot) {
Map<String, dynamic> mappedData = doc.data;
String un = mappedData["username"]; // Extracting every username in the document snapshot
usernames.add(un);
}
final List<Text> children = usernames.map((user) => Text(user)).toList(); /// Mapping the username into a Text Widget, I don't know if I did this part right
return Container (
child: ListView(
children: children,
),
);
} else {
return circularProgress(); // Check that you got this part right
}
}
),
);
}
}
This should work for you. Let me know if it works! :)
(Note: I have already asked this on pybind11's GitHub. Reaching to SO for wider audience. Tagging boost.python too in case someone has insight, but the question is about how to do this with pybind11)
Environment: Ubuntu 18.04, GCC 7.4.0, Python 3.6.9, pybind11 2.4.3
Suppose we want to wrap with pybind11 a shared library libfoo.so, exporting a base class Foo (i.e., with a vtable, in this case just a virtual destructor).
Exporting the whole class: OK
If we export the whole class (i.e., add visibility("default") to the whole class), then everything works as expected:
CMakeLists.txt
cmake_minimum_required(VERSION 3.1.0)
add_subdirectory(pybind11)
add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES CXX_VISIBILITY_PRESET hidden)
pybind11_add_module(pyfoo pyfoo.cpp)
target_link_libraries(pyfoo PRIVATE foo)
foo.h
#define FOO_API __attribute__((visibility("default")))
class FOO_API Foo { public: virtual ~Foo(); };
foo.cpp
#include "foo.h"
Foo::~Foo() {}
pyfoo.cpp
#include <pybind11/pybind11.h>
#include "foo.h"
PYBIND11_MODULE(pyfoo, m) {
pybind11::class_<Foo>(m, "Foo")
.def(pybind11::init<>());
}
test.py
import pyfoo
f = pyfoo.Foo()
print("Test succeeded")
Build and run:
$ mkdir build && cd build && cmake .. && make
$ PYTHONPATH=. python3 ../test.py
Test succeeded
Partially exporting the class: Segfault
However, my understanding is that to minimize the number of exported symbols, it is better practice to selectively export a desired selection of member functions, rather than the whole class. For a concrete example, see SdfData as part of Pixar's USD.
In our minimal example, this would look like the following (note that the FOO_API is now declared specifically for the destructor, not the whole class):
foo.h
#define FOO_API __attribute__((visibility("default")))
class Foo { public: FOO_API virtual ~Foo(); };
Build and run:
$ make
$ PYTHONPATH=. python3 ../test.py
Segmentation fault (core dumped)
(Note that it doesn't matter if the virtual method is the destructor or another method. The mere presence of a virtual method causes a segfault when the whole class isn't exported, even if such virtual method isn't wrapped. There is no segfault if we remove virtual from the above example)
Questions
Is this a bug?
If not, is there any workaround/method to be able to partially export a base class with virtual methods? The issue seems to be that there are missing exported typeinfo/vtable from the shared library: is there a way to explicitly export those without having to export the whole class?
More debug info
When exporting the whole class:
$ nm -o -C -D *.so | grep "Foo"
libfoo.so:0000000000000818 T Foo::~Foo()
libfoo.so:00000000000007fa T Foo::~Foo()
libfoo.so:00000000000007fa T Foo::~Foo()
libfoo.so:0000000000200df8 V typeinfo for Foo
libfoo.so:000000000000084d V typeinfo name for Foo
libfoo.so:0000000000200dd8 V vtable for Foo
pyfoo.cpython-36m-x86_64-linux-gnu.so: U typeinfo for Foo
pyfoo.cpython-36m-x86_64-linux-gnu.so: U vtable for Foo
When exporting the destructor only:
$ nm -o -C -D *.so | grep "Foo"
libfoo.so:0000000000000794 T Foo::~Foo()
libfoo.so:000000000000077a T Foo::~Foo()
libfoo.so:000000000000077a T Foo::~Foo()
pyfoo.cpython-36m-x86_64-linux-gnu.so: U typeinfo for Foo
pyfoo.cpython-36m-x86_64-linux-gnu.so: U vtable for Foo
Stacktrace (the segfault is with the import pyfoo call)
$ PYTHONPATH=. gdb python3
(gdb) r ../test.py
Starting program: /usr/bin/python3 ../test.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff42b72a9 in GlobalError::PushToStack() () from /usr/lib/x86_64-linux-gnu/libapt-pkg.so.5.0
(gdb) bt
#0 0x00007ffff42b72a9 in GlobalError::PushToStack() () from /usr/lib/x86_64-linux-gnu/libapt-pkg.so.5.0
#1 0x00007ffff433b082 in pkgInitConfig(Configuration&) () from /usr/lib/x86_64-linux-gnu/libapt-pkg.so.5.0
#2 0x00007ffff45d8ed8 in ?? () from /usr/lib/python3/dist-packages/apt_pkg.cpython-36m-x86_64-linux-gnu.so
#3 0x000000000050a8af in ?? ()
#4 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#5 0x0000000000508245 in ?? ()
#6 0x00000000005167b9 in ?? ()
#7 0x00000000005678ee in PyCFunction_Call ()
#8 0x000000000051171e in _PyEval_EvalFrameDefault ()
#9 0x0000000000508245 in ?? ()
#10 0x000000000050a080 in ?? ()
#11 0x000000000050aa7d in ?? ()
#12 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#13 0x0000000000509d48 in ?? ()
#14 0x000000000050aa7d in ?? ()
#15 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#16 0x0000000000509d48 in ?? ()
#17 0x000000000050aa7d in ?? ()
#18 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#19 0x0000000000509d48 in ?? ()
#20 0x000000000050aa7d in ?? ()
#21 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#22 0x0000000000509455 in _PyFunction_FastCallDict ()
#23 0x00000000005a55a1 in _PyObject_FastCallDict ()
#24 0x00000000005a65de in _PyObject_CallMethodIdObjArgs ()
#25 0x00000000004f729d in PyImport_ImportModuleLevelObject ()
#26 0x000000000050e4f1 in _PyEval_EvalFrameDefault ()
#27 0x0000000000508245 in ?? ()
#28 0x00000000005167b9 in ?? ()
#29 0x00000000005678ee in PyCFunction_Call ()
#30 0x000000000051171e in _PyEval_EvalFrameDefault ()
#31 0x0000000000508245 in ?? ()
#32 0x000000000050a080 in ?? ()
#33 0x000000000050aa7d in ?? ()
#34 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#35 0x0000000000509d48 in ?? ()
#36 0x000000000050aa7d in ?? ()
#37 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#38 0x0000000000509d48 in ?? ()
#39 0x000000000050aa7d in ?? ()
#40 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#41 0x0000000000509d48 in ?? ()
#42 0x000000000050aa7d in ?? ()
#43 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#44 0x0000000000509455 in _PyFunction_FastCallDict ()
#45 0x00000000005a55a1 in _PyObject_FastCallDict ()
#46 0x00000000005a65de in _PyObject_CallMethodIdObjArgs ()
#47 0x00000000004f729d in PyImport_ImportModuleLevelObject ()
#48 0x000000000050e4f1 in _PyEval_EvalFrameDefault ()
#49 0x0000000000508245 in ?? ()
#50 0x00000000005167b9 in ?? ()
#51 0x00000000005678ee in PyCFunction_Call ()
#52 0x000000000051171e in _PyEval_EvalFrameDefault ()
#53 0x0000000000508245 in ?? ()
#54 0x000000000050a080 in ?? ()
#55 0x000000000050aa7d in ?? ()
#56 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#57 0x0000000000509d48 in ?? ()
#58 0x000000000050aa7d in ?? ()
#59 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#60 0x0000000000509d48 in ?? ()
#61 0x000000000050aa7d in ?? ()
#62 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#63 0x0000000000509d48 in ?? ()
#64 0x000000000050aa7d in ?? ()
#65 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#66 0x0000000000509455 in _PyFunction_FastCallDict ()
#67 0x00000000005a55a1 in _PyObject_FastCallDict ()
#68 0x00000000005a65de in _PyObject_CallMethodIdObjArgs ()
#69 0x00000000004f729d in PyImport_ImportModuleLevelObject ()
#70 0x000000000050e4f1 in _PyEval_EvalFrameDefault ()
#71 0x0000000000508245 in ?? ()
#72 0x00000000005167b9 in ?? ()
#73 0x00000000005678ee in PyCFunction_Call ()
#74 0x000000000051171e in _PyEval_EvalFrameDefault ()
#75 0x0000000000508245 in ?? ()
#76 0x000000000050a080 in ?? ()
#77 0x000000000050aa7d in ?? ()
#78 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#79 0x0000000000509d48 in ?? ()
---Type <return> to continue, or q <return> to quit---
#80 0x000000000050aa7d in ?? ()
#81 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#82 0x0000000000509d48 in ?? ()
#83 0x000000000050aa7d in ?? ()
#84 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#85 0x0000000000509d48 in ?? ()
#86 0x000000000050aa7d in ?? ()
#87 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#88 0x0000000000509455 in _PyFunction_FastCallDict ()
#89 0x00000000005a55a1 in _PyObject_FastCallDict ()
#90 0x00000000005a65de in _PyObject_CallMethodIdObjArgs ()
#91 0x00000000004f729d in PyImport_ImportModuleLevelObject ()
#92 0x000000000050e4f1 in _PyEval_EvalFrameDefault ()
#93 0x0000000000508245 in ?? ()
#94 0x00000000005167b9 in ?? ()
#95 0x00000000005678ee in PyCFunction_Call ()
#96 0x000000000051171e in _PyEval_EvalFrameDefault ()
#97 0x0000000000508245 in ?? ()
#98 0x000000000050a080 in ?? ()
#99 0x000000000050aa7d in ?? ()
#100 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#101 0x0000000000509d48 in ?? ()
#102 0x000000000050aa7d in ?? ()
#103 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#104 0x0000000000509d48 in ?? ()
#105 0x000000000050aa7d in ?? ()
#106 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#107 0x0000000000509d48 in ?? ()
#108 0x000000000050aa7d in ?? ()
#109 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#110 0x0000000000509455 in _PyFunction_FastCallDict ()
#111 0x00000000005a55a1 in _PyObject_FastCallDict ()
#112 0x00000000005a65de in _PyObject_CallMethodIdObjArgs ()
#113 0x00000000004f729d in PyImport_ImportModuleLevelObject ()
#114 0x0000000000514804 in ?? ()
#115 0x00000000005678b3 in PyCFunction_Call ()
#116 0x000000000051171e in _PyEval_EvalFrameDefault ()
#117 0x0000000000508245 in ?? ()
#118 0x000000000050a080 in ?? ()
#119 0x000000000050aa7d in ?? ()
#120 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#121 0x0000000000509d48 in ?? ()
#122 0x000000000050aa7d in ?? ()
#123 0x000000000050c5b9 in _PyEval_EvalFrameDefault ()
#124 0x0000000000509455 in _PyFunction_FastCallDict ()
#125 0x00000000005a55a1 in _PyObject_FastCallDict ()
#126 0x00000000005a65de in _PyObject_CallMethodIdObjArgs ()
#127 0x00000000004f729d in PyImport_ImportModuleLevelObject ()
#128 0x000000000050e4f1 in _PyEval_EvalFrameDefault ()
#129 0x0000000000509455 in _PyFunction_FastCallDict ()
#130 0x00000000005a55a1 in _PyObject_FastCallDict ()
#131 0x00000000006386cb in PyErr_PrintEx ()
#132 0x0000000000638ab3 in PyRun_SimpleFileExFlags ()
#133 0x0000000000639631 in Py_Main ()
#134 0x00000000004b0f40 in main ()
As per C++ documentation, control block of the shared_ptr is thread-safe. ie, operator= or reset are accessible to multiple threads without explicit locking.
But I see a strange behavior; shared object is double freed occasionally:
#include <iostream>
#include <memory>
#include <unistd.h>
using namespace std;
class MyClass {
public:
MyClass(string x) : name(x) {cout<<"C->"<<name<<endl;};
~MyClass() {cerr<<"D->"<<name<<endl;};
string name;
};
shared_ptr<MyClass> a;
void* tfunc(void*) {
while(1){
{
shared_ptr<MyClass> s = a;
usleep(5);
}
}
}
int main(void) {
pthread_t threadid;
a = make_shared<MyClass>("a");
if(pthread_create(&threadid, NULL, tfunc, NULL)) {
cout<<"pthread_create error"<<endl;
return -1;
}
while(1){
usleep(5);
a = make_shared<MyClass>("b");
}
pthread_join(threadid, NULL);
return 0;
}
Here is the Address Sanitizer output:
==28588==ERROR: AddressSanitizer: heap-use-after-free on address 0xb33a7ad4 at pc 0x080490c4 bp 0xb54ff1d8 sp 0xb54ff1c8
WRITE of size 4 at 0xb33a7ad4 thread T1
#0 0x80490c3 in __exchange_and_add /usr/include/c++/6/ext/atomicity.h:49
#1 0x80491ed in __exchange_and_add_dispatch /usr/include/c++/6/ext/atomicity.h:82
#2 0x8049a9e in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/6/bits/shared_ptr_base.h:147
#3 0x80498a3 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/6/bits/shared_ptr_base.h:662
#4 0x804977e in std::__shared_ptr<MyClass, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/6/bits/shared_ptr_base.h:928
#5 0x8049797 in std::shared_ptr<MyClass>::~shared_ptr() /usr/include/c++/6/bits/shared_ptr.h:93
#6 0x80492d7 in tfunc(void*) /tmp/main.cpp:19
#7 0xb7248c4e (/usr/lib/i386-linux-gnu/libasan.so.3+0x26c4e)
#8 0xb6ea5304 in start_thread (/lib/i386-linux-gnu/libpthread.so.0+0x6304)
#9 0xb6fb347d in __clone (/lib/i386-linux-gnu/libc.so.6+0xe947d)
0xb33a7ad4 is located 4 bytes inside of 36-byte region [0xb33a7ad0,0xb33a7af4)
freed by thread T0 here:
#0 0xb72e7174 in operator delete(void*) (/usr/lib/i386-linux-gnu/libasan.so.3+0xc5174)
#1 0x804ace0 in __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<MyClass, std::allocator<MyClass>, (__gnu_cxx::_Lock_policy)2> >::deallocate(std::_Sp_counted_ptr_inplace<MyClass, std::allocator<MyClass>, (__gnu_cxx::_Lock_policy)2>*, unsigned int) /usr/include/c++/6/ext/new_allocator.h:110
#2 0x804ab07 in std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<MyClass, std::allocator<MyClass>, (__gnu_cxx::_Lock_policy)2> > >::deallocate(std::allocator<std::_Sp_counted_ptr_inplace<MyClass, std::allocator<MyClass>, (__gnu_cxx::_Lock_policy)2> >&, std::_Sp_counted_ptr_inplace<MyClass, std::allocator<MyClass>, (__gnu_cxx::_Lock_policy)2>*, unsigned int) /usr/include/c++/6/bits/alloc_traits.h:442
#3 0x804a818 in std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<MyClass, std::allocator<MyClass>, (__gnu_cxx::_Lock_policy)2> > >::~__allocated_ptr() /usr/include/c++/6/bits/allocated_ptr.h:73
#4 0x804b0aa in std::_Sp_counted_ptr_inplace<MyClass, std::allocator<MyClass>, (__gnu_cxx::_Lock_policy)2>::_M_destroy() /usr/include/c++/6/bits/shared_ptr_base.h:537
#5 0x8049bbe in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/include/c++/6/bits/shared_ptr_base.h:166
#6 0x80498a3 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/include/c++/6/bits/shared_ptr_base.h:662
#7 0x804977e in std::__shared_ptr<MyClass, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/include/c++/6/bits/shared_ptr_base.h:928
#8 0x8049cd4 in std::__shared_ptr<MyClass, (__gnu_cxx::_Lock_policy)2>::operator=(std::__shared_ptr<MyClass, (__gnu_cxx::_Lock_policy)2>&&) /usr/include/c++/6/bits/shared_ptr_base.h:1003
#9 0x8049a7c in std::shared_ptr<MyClass>::operator=(std::shared_ptr<MyClass>&&) /usr/include/c++/6/bits/shared_ptr.h:294
#10 0x8049430 in main /tmp/main.cpp:35
#11 0xb6ee2275 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18275)
GCC-6.2 and LLVM-3.9 show same behavior. Is it a bug in the C++ library?
No. = and reset are not thread safe. The shared_ptr overloads of std::atomic_... functions are needed.
"Control block is thread-safe" means you can use = and reset in multiple threads (but each thread uses a separate shared_ptr), even if all shared_ptr objects are copies of each other.
I have written a user space program that should install a new route in routing table. What i am noticing is , no if bytes sendmsg fn returns is correct, yet program is failing to install a new route. When i try to diagnose a problem using gdb on linux kernel, i find that garbage data is being sent from user space to kernel netlink socket.
output
[root#localhost rtnetlink]# ./netlink_add_route.exe
bytes send = 52
Sharing code:
typedef struct _request
{
struct nlmsghdr netlink_header;
struct rtmsg rt_message;
char buffer[1024];
} req_t;
int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
{
/* alen is the length of the data. Add sizeof(struct rtattr) to it to accomodate
type, length, value format for rtattr */
int len = RTA_LENGTH(alen); // (RTA_ALIGN(sizeof(struct rtattr)) + (len))
struct rtattr *rta;
/* size of request should not be violated*/
if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen)
return -1;
/* go to end of buffer in request data structure*/
rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len));
/* specify attribute using TLV format*/
rta->rta_type = type;
rta->rta_len = len;
memcpy(RTA_DATA(rta), data, alen);
/* increase the nlmsg_len to accomodate the added new attribute*/
n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
return 0;
}
static void
initialisation(){
/* initialise the request structure*/
int index = 3,
gw = 3232236545/*192.168.4.1*/,
dst = 3232235776/*192.168.1.0*/;
memset(&request, 0, sizeof(request));
/* set the nlmsg_len = nl header + underlying structure*/
request.netlink_header.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); /*NLMSG_HDRLEN + sizeof(struct rtmsg);*/
/* set the flags that facilitates adding a route in routing table*/
request.netlink_header.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE;
/* note that inet_rtm_newroute() is the fn in kernel which will be eventually called to add a new route in routing table*/
request.netlink_header.nlmsg_type = RTM_NEWROUTE;
/* Now filling the rtmsg*/
request.rt_message.rtm_family = AF_INET;
request.rt_message.rtm_table = RT_TABLE_MAIN;
request.rt_message.rtm_protocol = RTPROT_BOOT;/*Route installed during boot*/
request.rt_message.rtm_scope = RT_SCOPE_UNIVERSE;
request.rt_message.rtm_type = RTN_UNICAST; /*Gateway or direct route */
/* Add routing info*/
addattr_l(&request.netlink_header, sizeof(request), RTA_GATEWAY, &gw, sizeof(gw));
addattr_l(&request.netlink_header, sizeof(request), RTA_DST, &dst, sizeof(dst));
addattr_l(&request.netlink_header, sizeof(request), RTA_OIF, &index, sizeof(index));
/* For adding a route, the gateway, destination address and the interface
will suffice, now the netlink packet is all set to go to the kernel*/
}
static void
send_request(int fd){
int rc = 0;
struct msghdr msg;
struct sockaddr_nl nladdr;
struct iovec iov;
iov.iov_base = (void*)&request.netlink_header;
iov.iov_len = request.netlink_header.nlmsg_len ;/* Total length : from request start to end of last attribute*/
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
nladdr.nl_pid = 0; /* For Linux Kernel */
nladdr.nl_groups = 0;
msg.msg_name = (void *)&nladdr;
msg.msg_namelen = sizeof(nladdr);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
rc = sendmsg(fd, &msg, 0);
printf("bytes send = %d\n", rc);
}
int
main(int argc, char *argv[])
{
struct sockaddr_nl la;
int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if(fd < 0){
printf("socket creation failed\n");
return -1;
}
bzero(&la, sizeof(la));
la.nl_family = AF_NETLINK;
la.nl_pid = getpid();
la.nl_groups = 0;
if(bind(fd, (struct sockaddr*) &la, sizeof(la)) < 0){
printf("Bind failed\n");
return -1;
}
initialisation();
send_request(fd);
close(fd);
}
gdb output
Breakpoint 1, inet_rtm_newroute (skb=0xbb53f20, nlh=0xb96ed00) at net/ipv4/fib_frontend.c:732
732 {
(gdb) bt
#0 inet_rtm_newroute (skb=0xbb53f20, nlh=0xb96ed00) at net/ipv4/fib_frontend.c:732
#1 0x081f1b28 in rtnetlink_rcv_msg (skb=0xbb53f20, nlh=0xb96ed00) at net/core/rtnetlink.c:3412
#2 0x081fcd07 in netlink_rcv_skb (skb=0xbb53f20, cb=0x81f19de <rtnetlink_rcv_msg>)
at net/netlink/af_netlink.c:3017
#3 0x081efcb9 in rtnetlink_rcv (skb=0xbb53f20) at net/core/rtnetlink.c:3418
#4 0x081fc7e4 in netlink_unicast_kernel (ssk=<optimized out>, skb=<optimized out>, sk=<optimized out>) at net/netlink/af_netlink.c:1834
#5 netlink_unicast (ssk=0xbb03000, skb=0xbb53f20, portid=0, nonblock=0) at net/netlink/af_netlink.c:1860
#6 0x081fcbf3 in netlink_sendmsg (sock=0xa50a700, msg=0xbb71e3c, len=52) at net/netlink/af_netlink.c:2511
#7 0x081cf181 in sock_sendmsg_nosec (msg=<optimized out>, sock=<optimized out>) at net/socket.c:611
#8 sock_sendmsg (sock=0xa50a700, msg=<optimized out>) at net/socket.c:621
#9 0x081cf781 in ___sys_sendmsg (sock=0xa50a700, msg=<optimized out>, msg_sys=0xbb71e3c, flags=0,
used_address=0x0) at net/socket.c:1947
#10 0x081d044f in __sys_sendmsg (fd=3, msg=0xbfd5cc40, flags=0) at net/socket.c:1981
#11 0x081d0a97 in SYSC_sendmsg (flags=<optimized out>, msg=<optimized out>, fd=<optimized out>)
at net/socket.c:1992
#12 SyS_sendmsg (flags=0, msg=-1076507584, fd=3) at net/socket.c:1988
#13 SYSC_socketcall (args=<optimized out>, call=<optimized out>) at net/socket.c:2397
#14 SyS_socketcall (call=16, args=-1076507632) at net/socket.c:2315
#15 0x0805ba59 in handle_syscall (r=0xbbab3f0) at arch/um/kernel/skas/syscall.c:37
#16 0x08069147 in handle_trap (local_using_sysemu=<optimized out>, regs=<optimized out>,
pid=<optimized out>) at arch/um/os-Linux/skas/process.c:172
#17 userspace (regs=0xbbab3f0) at arch/um/os-Linux/skas/process.c:384
#18 0x080594df in fork_handler () at arch/um/kernel/process.c:154
#19 0x00000000 in ?? ()
(gdb) f 6
#6 0x081fcbf3 in netlink_sendmsg (sock=0xa50a700, msg=0xbb71e3c, len=52) at net/netlink/af_netlink.c:2511
2511 err = netlink_unicast(sk, skb, dst_portid, msg->msg_flags&MSG_DONTWAIT);
(gdb) p msg
$1 = (struct msghdr *) 0xbb71e3c
(gdb) p *(struct msghdr *) 0xbb71e3c
$2 = {msg_name = 0xbb71d98, msg_namelen = 12, msg_iter = {type = 1, iov_offset = 0, count = 0, {
iov = 0xbb71d60, kvec = 0xbb71d60, bvec = 0xbb71d60}, nr_segs = 0}, msg_control = 0x4,
msg_controllen = 0, msg_flags = 0, msg_iocb = 0x0}
(gdb) f 10
#10 0x081d044f in __sys_sendmsg (fd=3, msg=0xbfd5cc40, flags=0) at net/socket.c:1981
1981 err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
(gdb) p msg
$3 = (struct user_msghdr *) 0xbfd5cc40
(gdb) p *(struct user_msghdr *) 0xbfd5cc40
Cannot access memory at address 0xbfd5cc40
As you can see above, the msg recieved in kernel is not accessible. When i apply the gdb on sendmsg fn in application and expand the msg being sent to kernel, i find everything perfect. What is causing this msg corruption in between user space and kernel ? Can anyone pls help diagnose the issue ?
I am using kernel version 4.5.3.
sharing the link to src file if someone wants to run the program.
https://drive.google.com/file/d/0B56H_R1fVFZXRjNWRkZ3M09pY2s/view?usp=sharing
Thanks.
I could successfully make it work. The issue is the way RTA_DST and RTA_GATEWAY is added. You need to use inet_prefix for dst.
Please note dst.data[],dst.bytelen and dst.bitlen are all just some random values. Please initialize as required for your solution. (this is just to demonstrate that it works!)
typedef struct
{
__u16 flags;
__u16 bytelen;
__s16 bitlen;
__u16 family;
__u32 data[8];
} inet_prefix;
inet_prefix dst;
dst.data[0] = 11;
dst.data[1] = 12;
dst.data[2] = 13;
dst.data[3] = 14;
dst.data[4] = 15;
dst.data[5] = 16;
dst.data[6] = 17;
dst.data[7] = 17;
dst.bytelen = 32;
dst.bitlen = dst.bytelen * 8;
/* mask */
request.rt_message.rtm_dst_len = 24;
//addattr_l(&request.netlink_header, sizeof(request), RTA_GATEWAY, &gw, sizeof(gw));
addattr_l(&request.netlink_header, sizeof(request), RTA_DST, &dst, sizeof(dst));
As a sample I added 'dst' entry and commented out 'gw' entry.
For 'gw' too you have to follow similar struct inet_prefix.
Entry created:
12.0.32.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0