Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added/Fixed null pointer checks #10591

Merged

Conversation

Rubonnek
Copy link
Member

@Rubonnek Rubonnek commented Aug 23, 2017

This pull request mitigates some cppcheck messages related to null pointer
dereferencing. Hopefully this will cover most of the segfaults that could occur when compiling with GCC 7.1.1:

Starting to edit a collision shape and clicking on a different node of the scene tree will trigger a segmentation fault. A fix was applied and mitigates the following message:

[editor/plugins/collision_shape_2d_editor_plugin.cpp:573]: (warning, inconclusive) Possible null pointer dereference: p_obj

The following messages were also mitigates which seemed like bugs or unneeded code:

[editor/plugins/rich_text_editor_plugin.cpp:94]: (warning, inconclusive) Possible null pointer dereference: p_rich_text
[editor/animation_editor.cpp:1638] -> [editor/animation_editor.cpp:1650]: (warning, inconclusive) Either the condition 'node' is redundant or there is possible null pointer dereference: node.
[modules/visual_script/visual_script_func_nodes.cpp:828] -> [modules/visual_script/visual_script_func_nodes.cpp:827]: (warning, inconclusive) Either the condition '!node' is redundant or there is possible null pointer dereference: node.
[modules/visual_script/visual_script_func_nodes.cpp:1606] -> [modules/visual_script/visual_script_func_nodes.cpp:1605]: (warning, inconclusive) Either the condition '!node' is redundant or there is possible null pointer dereference: node.
[modules/visual_script/visual_script_func_nodes.cpp:2253] -> [modules/visual_script/visual_script_func_nodes.cpp:2252]: (warning, inconclusive) Either the condition '!node' is redundant or there is possible null pointer dereference: node.
[modules/visual_script/visual_script_nodes.cpp:2090] -> [modules/visual_script/visual_script_nodes.cpp:2089]: (warning, inconclusive) Either the condition '!node' is redundant or there is possible null pointer dereference: node.
[modules/visual_script/visual_script_yield_nodes.cpp:541] -> [modules/visual_script/visual_script_yield_nodes.cpp:540]: (warning, inconclusive) Either the condition '!node' is redundant or there is possible null pointer dereference: node.
[servers/visual/visual_server_scene.cpp:2058] -> [servers/visual/visual_server_scene.cpp:2064]: (warning) Either the condition 'light' is redundant or there is possible null pointer dereference: light.
[editor/editor_node.cpp:1294]: (warning, inconclusive) Possible null pointer dereference: current_obj
[editor/editor_node.cpp:1296]: (warning, inconclusive) Possible null pointer dereference: current_obj
[editor/editor_node.cpp:2276]: (warning, inconclusive) Possible null pointer dereference: current_obj
[editor/editor_node.cpp:2278]: (warning, inconclusive) Possible null pointer dereference: current_obj
[editor/editor_node.cpp:2288]: (warning, inconclusive) Possible null pointer dereference: current_obj
[editor/editor_node.cpp:2290]: (warning, inconclusive) Possible null pointer dereference: current_obj
[editor/editor_node.cpp:2300]: (warning, inconclusive) Possible null pointer dereference: current_obj
[editor/editor_node.cpp:2302]: (warning, inconclusive) Possible null pointer dereference: current_obj
[editor/editor_node.cpp:2311]: (warning, inconclusive) Possible null pointer dereference: current_obj
[editor/editor_node.cpp:2313]: (warning, inconclusive) Possible null pointer dereference: current_obj
[drivers/gles3/rasterizer_gles3.cpp:250] -> [drivers/gles3/rasterizer_gles3.cpp:257]: (warning) Either the condition '!rt' is redundant or there is possible null pointer dereference: rt.
[platform/x11/power_x11.cpp:259] -> [platform/x11/power_x11.cpp:256]: (warning, inconclusive) Either the condition 'dirp==NULL' is redundant or there is possible null pointer dereference: dirp.
[platform/x11/power_x11.cpp:259] -> [platform/x11/power_x11.cpp:257]: (warning, inconclusive) Either the condition 'dirp==NULL' is redundant or there is possible null pointer dereference: dirp.
[platform/x11/power_x11.cpp:272] -> [platform/x11/power_x11.cpp:270]: (warning, inconclusive) Either the condition 'dirp==NULL' is redundant or there is possible null pointer dereference: dirp.
[platform/x11/power_x11.cpp:272] -> [platform/x11/power_x11.cpp:271]: (warning, inconclusive) Either the condition 'dirp==NULL' is redundant or there is possible null pointer dereference: dirp.
[platform/x11/power_x11.cpp:443] -> [platform/x11/power_x11.cpp:440]: (warning, inconclusive) Either the condition '!dirp' is redundant or there is possible null pointer dereference: dirp.
[platform/x11/power_x11.cpp:443] -> [platform/x11/power_x11.cpp:441]: (warning, inconclusive) Either the condition '!dirp' is redundant or there is possible null pointer dereference: dirp.
[editor/editor_settings.cpp:250] -> [editor/editor_settings.cpp:249]: (warning, inconclusive) Either the condition '!file' is redundant or there is possible null pointer dereference: file.
[scene/gui/tree.cpp:2872] -> [scene/gui/tree.cpp:2871]: (warning) Either the condition '!ti' is redundant or there is possible null pointer dereference: ti.
[servers/visual/visual_server_canvas.cpp:1102] -> [servers/visual/visual_server_canvas.cpp:1105]: (warning) Either the condition '!occluder_poly' is redundant or there is possible null pointer dereference: occluder_poly.
[servers/visual/visual_server_canvas.cpp:1102] -> [servers/visual/visual_server_canvas.cpp:1106]: (warning) Either the condition '!occluder_poly' is redundant or there is possible null pointer dereference: occluder_poly.
[servers/visual/visual_server_canvas.cpp:1102] -> [servers/visual/visual_server_canvas.cpp:1107]: (warning) Either the condition '!occluder_poly' is redundant or there is possible null pointer dereference: occluder_poly.
[servers/visual/visual_server_canvas.cpp:1102] -> [servers/visual/visual_server_canvas.cpp:1108]: (warning) Either the condition '!occluder_poly' is redundant or there is possible null pointer dereference: occluder_poly.

As far as I can tell, all of the following possible null dereferences seem to have already been
accounted for previously and I did not provide any fixes for these. I'm
including their relevant code blocks in any case for easier inspection, but I don't mind mitigating these messages if required:

cppcheck message:

[drivers/gles3/shader_compiler_gles3.cpp:243]: (warning) Possible null pointer dereference: fnode

relevant codeblock:

  • fnode was already accounted for in line 239
    SL::FunctionNode *fnode = NULL;
    for (int i = 0; i < p_node->functions.size(); i++) {
    if (p_node->functions[i].name == E->get()) {
    fnode = p_node->functions[i].function;
    break;
    }
    }
    ERR_FAIL_COND(!fnode);
    r_to_add += "\n";
    String header;
    header = _typestr(fnode->return_type) + " " + _mkid(fnode->name) + "(";

cppcheck message:

[editor/editor_dir_dialog.cpp:149] -> [editor/editor_dir_dialog.cpp:157]: (warning, inconclusive) Either the condition 'p' is redundant or there is possible null pointer dereference: p.

relevant codeblock:

  • p was accounted for in line 156

TreeItem *p = r->get_children();
while (p) {
if (p->get_text(0) == d)
break;
p = p->get_next();
}
ERR_FAIL_COND(!p);
String pp = p->get_metadata(0);

cppcheck message:

[editor/editor_export.cpp:661] -> [editor/editor_export.cpp:671]: (warning, inconclusive) Either the condition '!ftmp' is redundant or there is possible null pointer dereference: ftmp.

relevant codeblock:

  • ftmp was accounted for in the first if statement below

ftmp = FileAccess::open(tmppath, FileAccess::READ);
if (!ftmp) {
memdelete(f);
ERR_FAIL_COND_V(!ftmp, ERR_CANT_CREATE)
}
const int bufsize = 16384;
uint8_t buf[bufsize];
while (true) {
int got = ftmp->get_buffer(buf, bufsize);
if (got <= 0)
break;
f->store_buffer(buf, got);
}

cppcheck message:

[editor/editor_node.cpp:4659]: (warning, inconclusive) Possible null pointer dereference: dock

relevant codeblock:

  • dock was accounted for in line 4657

godot/editor/editor_node.cpp

Lines 4646 to 4661 in b4ad899

void EditorNode::remove_control_from_dock(Control *p_control) {
Control *dock = NULL;
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
if (p_control->get_parent() == dock_slot[i]) {
dock = dock_slot[i];
break;
}
}
ERR_EXPLAIN("Control was not in dock");
ERR_FAIL_COND(!dock);
dock->remove_child(p_control);
_update_dock_slots_visibility();
}

cppcheck message:

[editor/scene_tree_dock.cpp:1695]: (warning, inconclusive) Possible null pointer dereference: to_node
[editor/scene_tree_dock.cpp:1696]: (warning, inconclusive) Possible null pointer dereference: to_node

relevant codeblocks:

  • I don't think we need a fix for this -- to_node only comes from two
    different sources:

  • to_node was already accounted for in line 1751 as the node variable:

void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_type) {
Node *node = get_node(p_to);
ERR_FAIL_COND(!node);
int to_pos = -1;
_normalize_drop(node, to_pos, p_type);
_perform_instance_scenes(p_files, node, to_pos);
}

  • to_node was already accounted for in line 1783:

void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) {
Vector<Node *> nodes;
Node *to_node;
for (int i = 0; i < p_nodes.size(); i++) {
Node *n = get_node((p_nodes[i]));
if (n) {
nodes.push_back(n);
}
}
if (nodes.size() == 0)
return;
to_node = get_node(p_to);
if (!to_node)
return;
int to_pos = -1;
_normalize_drop(to_node, to_pos, p_type);
_do_reparent(to_node, to_pos, nodes, true);
}

  • And this is the code block cppcheck points to:

void SceneTreeDock::_normalize_drop(Node *&to_node, int &to_pos, int p_type) {
to_pos = -1;
if (p_type == -1) {
//drop at above selected node
if (to_node == EditorNode::get_singleton()->get_edited_scene()) {
to_node = NULL;
ERR_EXPLAIN("Cannot perform drop above the root node!");
ERR_FAIL();
}
to_pos = to_node->get_index();
to_node = to_node->get_parent();

@Rubonnek Rubonnek force-pushed the possible-null-ptr-dereference branch 2 times, most recently from 1b66d25 to 25250dd Compare August 24, 2017 04:01
@akien-mga akien-mga added this to the 3.0 milestone Aug 24, 2017
@@ -1291,7 +1291,7 @@ void EditorNode::_dialog_action(String p_file) {
uint32_t current = editor_history.get_current();
Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL;

ERR_FAIL_COND(!current_obj->cast_to<Resource>())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem right, plus it would conflict with #10581.

Basically, ->cast_to was assumed to run on null pointers as well, and it would return null if (1) this == NULL, or (2) this couldn't be casted to the specified type.

Copy link
Member Author

@Rubonnek Rubonnek Aug 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will wait until #10581 gets merged, but using ->cast_to on null pointers is already causing segfaults with GCC 7.1.1. I fixed one on #10492 and you can see the full backtrace I got on #10372 after the segfault.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which is precisely what #10581 fixes :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right

file->reopen(p_path.plus_file((String)keys[i]), FileAccess::WRITE);
ERR_FAIL_COND(!file);
Error err = file->reopen(p_path.plus_file((String)keys[i]), FileAccess::WRITE);
ERR_FAIL_COND(!err);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should use err != OK (or Error::OK, if needed). This way, the error message would be clearer.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer !err, but yeah, err != OK is clearer. I'll do that.

@@ -247,9 +247,6 @@ void RasterizerGLES3::set_current_render_target(RID p_render_target) {

if (p_render_target.is_valid()) {
RasterizerStorageGLES3::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target);
if (!rt) {
storage->frame.current_rt = NULL;
}
ERR_FAIL_COND(!rt);
storage->frame.current_rt = rt;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if the new behaviour would be correct, but to get the old behaviour, you should move this line above ERR_FAIL_COND.

storage->frame.current_rt = rt;
ERR_FAIL_COND(!rt);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right. I'll fix that.

@RandomShaper
Copy link
Member

I think it's better to wait until #10581 is finished and re-run cppcheck then.

@Rubonnek
Copy link
Member Author

Rubonnek commented Aug 24, 2017

@RandomShaper Sounds good. I will do that then.

@@ -570,6 +570,9 @@ CollisionShape2DEditor::CollisionShape2DEditor(EditorNode *p_editor) {

void CollisionShape2DEditorPlugin::edit(Object *p_obj) {

if(!p_obj)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I keep getting these. I'll install the commit hooks :p

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CollisionShape2DEditor::edit() is null safe. This check is no longer required after #10581 either

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not. Like I mentioned in the first message:

Starting to edit a collision shape and clicking on a different node of the scene tree will trigger a segmentation fault.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be after #10581, I haven't checked it yet.

@@ -2308,7 +2308,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
uint32_t current = editor_history.get_current();
Object *current_obj = current > 0 ? ObjectDB::get_instance(current) : NULL;

ERR_FAIL_COND(!current_obj->cast_to<Resource>())
ERR_FAIL_COND(!current_obj)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checks in this block are not equivalent to the old code. This code only fails if current_obj is Null, while the previous code would also fail if current_obj couldn't cast to a Resource. Any crashes this used to produce will be fixed with #10581 now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing it out. I'm aware of that. My point on changing these was simply to avoid segmentation faults. I'm waiting for #10581 to get merged to rescan with cppcheck.

@hpvb
Copy link
Member

hpvb commented Aug 25, 2017

@Rubonnek #10581 got merged, it'd be fantastic if you could do this again. The remaining cases (particularly the 'another' logic error) could really improve engine stability.

@Rubonnek
Copy link
Member Author

@hpvb Thanks for letting me know. I'm on it.

@Rubonnek Rubonnek force-pushed the possible-null-ptr-dereference branch 3 times, most recently from 8cdd3d9 to 9b1b1be Compare August 25, 2017 15:27
@Rubonnek
Copy link
Member Author

After rescanning the master branch again, the following messages showed up and
were mitigated:

[drivers/gles3/rasterizer_gles3.cpp:250] -> [drivers/gles3/rasterizer_gles3.cpp:257]: (warning) Either the condition '!rt' is redundant or there is possible null pointer dereference: rt.
[editor/animation_editor.cpp:1638] -> [editor/animation_editor.cpp:1650]: (warning, inconclusive) Either the condition 'node' is redundant or there is possible null pointer dereference: node.
[editor/editor_settings.cpp:250] -> [editor/editor_settings.cpp:249]: (warning, inconclusive) Either the condition '!file' is redundant or there is possible null pointer dereference: file.
[modules/visual_script/visual_script_func_nodes.cpp:825] -> [modules/visual_script/visual_script_func_nodes.cpp:824]: (warning, inconclusive) Either the condition '!node' is redundant or there is possible null pointer dereference: node.
[modules/visual_script/visual_script_func_nodes.cpp:1599] -> [modules/visual_script/visual_script_func_nodes.cpp:1598]: (warning, inconclusive) Either the condition '!node' is redundant or there is possible null pointer dereference: node.
[modules/visual_script/visual_script_func_nodes.cpp:2244] -> [modules/visual_script/visual_script_func_nodes.cpp:2243]: (warning, inconclusive) Either the condition '!node' is redundant or there is possible null pointer dereference: node.
[modules/visual_script/visual_script_nodes.cpp:2090] -> [modules/visual_script/visual_script_nodes.cpp:2089]: (warning, inconclusive) Either the condition '!node' is redundant or there is possible null pointer dereference: node.
[modules/visual_script/visual_script_yield_nodes.cpp:538] -> [modules/visual_script/visual_script_yield_nodes.cpp:537]: (warning, inconclusive) Either the condition '!node' is redundant or there is possible null pointer dereference: node.
[platform/x11/power_x11.cpp:259] -> [platform/x11/power_x11.cpp:256]: (warning, inconclusive) Either the condition 'dirp==NULL' is redundant or there is possible null pointer dereference: dirp.
[platform/x11/power_x11.cpp:259] -> [platform/x11/power_x11.cpp:257]: (warning, inconclusive) Either the condition 'dirp==NULL' is redundant or there is possible null pointer dereference: dirp.
[platform/x11/power_x11.cpp:272] -> [platform/x11/power_x11.cpp:270]: (warning, inconclusive) Either the condition 'dirp==NULL' is redundant or there is possible null pointer dereference: dirp.
[platform/x11/power_x11.cpp:272] -> [platform/x11/power_x11.cpp:271]: (warning, inconclusive) Either the condition 'dirp==NULL' is redundant or there is possible null pointer dereference: dirp.
[platform/x11/power_x11.cpp:443] -> [platform/x11/power_x11.cpp:440]: (warning, inconclusive) Either the condition '!dirp' is redundant or there is possible null pointer dereference: dirp.
[platform/x11/power_x11.cpp:443] -> [platform/x11/power_x11.cpp:441]: (warning, inconclusive) Either the condition '!dirp' is redundant or there is possible null pointer dereference: dirp.
[scene/gui/text_edit.cpp:219]: (error) Null pointer dereference: cri
[scene/gui/tree.cpp:2872] -> [scene/gui/tree.cpp:2871]: (warning) Either the condition '!ti' is redundant or there is possible null pointer dereference: ti.
[servers/physics/broad_phase_basic.cpp:37]: (style) Condition 'p_object_==NULL' is always true
[servers/visual/visual_server_canvas.cpp:1102] -> [servers/visual/visual_server_canvas.cpp:1105]: (warning) Either the condition '!occluder_poly' is redundant or there is possible null pointer dereference: occluder_poly.
[servers/visual/visual_server_canvas.cpp:1102] -> [servers/visual/visual_server_canvas.cpp:1106]: (warning) Either the condition '!occluder_poly' is redundant or there is possible null pointer dereference: occluder_poly.
[servers/visual/visual_server_canvas.cpp:1102] -> [servers/visual/visual_server_canvas.cpp:1107]: (warning) Either the condition '!occluder_poly' is redundant or there is possible null pointer dereference: occluder_poly.
[servers/visual/visual_server_canvas.cpp:1102] -> [servers/visual/visual_server_canvas.cpp:1108]: (warning) Either the condition '!occluder_poly' is redundant or there is possible null pointer dereference: occluder_poly.
[servers/visual/visual_server_scene.cpp:2058] -> [servers/visual/visual_server_scene.cpp:2064]: (warning) Either the condition 'light' is redundant or there is possible null pointer dereference: light.

These showed up again but like I mentioned in the first post, these seem to be
already accounted for as far as I can tell:

[drivers/gles3/shader_compiler_gles3.cpp:244]: (warning) Possible null pointer dereference: fnode
[editor/editor_dir_dialog.cpp:149] -> [editor/editor_dir_dialog.cpp:157]: (warning, inconclusive) Either the condition 'p' is redundant or there is possible null pointer dereference: p.
[editor/editor_export.cpp:661] -> [editor/editor_export.cpp:671]: (warning, inconclusive) Either the condition '!ftmp' is redundant or there is possible null pointer dereference: ftmp.
[editor/editor_node.cpp:4659]: (warning, inconclusive) Possible null pointer dereference: dock
[editor/scene_tree_dock.cpp:1691]: (warning, inconclusive) Possible null pointer dereference: to_node
[editor/scene_tree_dock.cpp:1692]: (warning, inconclusive) Possible null pointer dereference: to_node

These messages are different to null pointer dereferencing and were not fixed
since we want these conditions to show up in the messages.

[scene/main/scene_tree.cpp:1931]: (style) Condition 'node==NULL' is always true
[scene/main/scene_tree.cpp:1949]: (style) Condition 'node==NULL' is always true

And this last message is a false positive that might show due to cppcheck not being configured properly:

[platform/x11/os_x11.cpp:137]: (style) Condition 'modifiers==NULL' is always true

@Rubonnek Rubonnek force-pushed the possible-null-ptr-dereference branch 4 times, most recently from 82c1849 to 75ceb82 Compare August 26, 2017 01:38
@Rubonnek
Copy link
Member Author

This pull request now also fixes #10638

@@ -3766,7 +3766,7 @@ bool CanvasItemEditorViewport::_cyclical_dependency_exists(const String &p_targe

void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String &path, const Point2 &p_point) {
child->set_name(path.get_file().get_basename());
Ref<Texture> texture = Object::cast_to<Texture>(Ref<Texture>(ResourceCache::get(path)).ptr());
Ref<Texture> texture = Ref<Texture>(Object::cast_to<Texture>(ResourceCache::get(path)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this! I'll go through the diff again and make sure I didn't make this mistake elsewhere (I apparently saw Ref and decided I needed to dereference, whoops)

Copy link
Member Author

@Rubonnek Rubonnek Aug 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anytime! You did fix a lot of issues in your pull request.

For what it's worth, I did a quick egrep to catch another line like that:

egrep -R "Object::cast_to<.*>\(.*Ref"

but nothing showed up. I think the rest is good.

@@ -215,9 +215,6 @@ void TextEdit::Text::_update_line_cache(int p_line) const {

const Map<int, TextEdit::Text::ColorRegionInfo> &TextEdit::Text::get_color_region_info(int p_line) {

Map<int, ColorRegionInfo> *cri = NULL;
ERR_FAIL_INDEX_V(p_line, text.size(), *cri); //enjoy your crash
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if just removing the debugging warning here is a good idea. In release mode this crash already doesn't exist. Maybe find out what's at the other end of this and return a value that won't crash?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe make it a fatal error rather than a warning.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that by removing the explicit handling, the container implementation will crash (on purpose) on index-out-of-bounds.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better to crash here though, for debugging purposes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it matters whether it crashes here or not. The backtrace will still point us to the right line.

You can try putting this in, say, the main function.

String text;
text[20]; // crashes here

This is the gdb message:

Program received signal SIGILL, Illegal instruction.
0x00005555556e7d49 in Vector<wchar_t>::operator[] (p_index=20, this=0x7fffffffdae8) at core/vector.h:137
137                     CRASH_BAD_INDEX(p_index, size());

And the backtrace you will get:

(gdb) bt
#0  0x00005555556e7d49 in Vector<wchar_t>::operator[] (p_index=20, this=0x7fffffffdae8) at core/vector.h:137
#1  main (argc=<optimized out>, argv=<optimized out>) at platform/x11/godot_x11.cpp:48

It's obvious what's happening just from that, which is why I think those two lines are unnecessary.

Copy link
Member

@akien-mga akien-mga Aug 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea is that for the end user, it's better to have the error message induced by ERR_FAIL_INDEX_V before a segfault that they won't know how to debug. This way they have something meaningful to report to us and not just a "it crashed". But I have no strong opinion either way.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll check how Godot behaves when those lines get executed in a Clang build then and see if I can get both builds to behave the same way while keeping the messages visible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the for loop to:

for (int i = -2000; i < cursor.line_ofs + 2000; i++) {

to trigger ERR_FAIL_INDEX_V crashes both builds.

But passing a static map keeps both builds from crashing:

	static Map<int, ColorRegionInfo> cri;
	ERR_FAIL_INDEX_V(p_line, text.size(), cri); //no more crashes on either builds

}

// Try to support IME if detectable auto-repeat is supported
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually that comment was at the right place, the detection of auto-repeat is that xkb_dar bool.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completely missed it when I was copy-pasting. I'll fix it. Thanks.

@@ -58,6 +58,7 @@ Adapted from corresponding SDL 2.0 code.
#include <stdio.h>
#include <unistd.h>

#include <core/error_macros.h>
Copy link
Member

@akien-mga akien-mga Aug 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Godot includes should use double quotes, <> are for system headers. So it should be:

#include "power_x11.h"

#include "core/error_macros.h"

#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <unistd.h>

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't aware of this standard. I'll fix it then.

@Rubonnek Rubonnek force-pushed the possible-null-ptr-dereference branch from 75ceb82 to 2b59660 Compare August 26, 2017 19:26
@Rubonnek Rubonnek force-pushed the possible-null-ptr-dereference branch from 2b59660 to 7a07895 Compare August 26, 2017 20:58
@akien-mga akien-mga merged commit 612099e into godotengine:master Aug 27, 2017
@Rubonnek Rubonnek deleted the possible-null-ptr-dereference branch August 27, 2017 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants