Skip to content

Instantly share code, notes, and snippets.

@lighth7015
Created February 16, 2020 17:31
Show Gist options
  • Save lighth7015/a2c2f875a1c1d2f2856c02ed762cb1d8 to your computer and use it in GitHub Desktop.
Save lighth7015/a2c2f875a1c1d2f2856c02ed762cb1d8 to your computer and use it in GitHub Desktop.
std::shared_ptr crash
(gdb) r
Starting program: /home/robert_/C++/intervue/bin/x86_64-pc-linux-gnu/debug/client 
/usr/lib/../share/gcc-9.2.0/python/libstdcxx/v6/xmethods.py:731: SyntaxWarning: list indices must be integers or slices, not str; perhaps you missed a comma?
  refcounts = ['_M_refcount']['_M_pi']
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
height is 16

ID = 1, Position = (231, 2)

height is 16

Program received signal SIGSEGV, Segmentation fault.
0x000055555555c583 in MDIWindowButton::MDIWindowButton (this=0x55555557b980, form=0x55555557b360, width=16, height=16, padding=2) at src/client/button.cpp:49
49                      printf("(x = %d, y = %d) Adjust? Previous btnId = %zu\n", previous->metrics.x, previous->metrics.y, prevBtnId);
(gdb) frame previous
Value can't be converted to integer.
(gdb) pritn previous
Undefined command: "pritn".  Try "help".
(gdb) print previous
$1 = <error reading variable: Cannot access memory at address 0x219>
(gdb) print buttons
$2 = std::vector of length 1, capacity 1 = {warning: RTTI symbol not found for class 'std::_Sp_counted_ptr_inplace<MDIWindowButton, std::allocator<MDIWindowButton>, (__gnu_cxx::_Lock_policy)2>'
warning: RTTI symbol not found for class 'std::_Sp_counted_ptr_inplace<MDIWindowButton, std::allocator<MDIWindowButton>, (__gnu_cxx::_Lock_policy)2>'
std::shared_ptr<MDIWindowButton> (use count 1, weak count 0) = {get() = 0x55555557b510}}
(gdb) print *buttons
No symbol "operator*" in current context.
(gdb) print buttons[1]
$3 = <error reading variable: Cannot access memory at address 0x219>
(gdb) print buttons[0]
$4 = warning: RTTI symbol not found for class 'std::_Sp_counted_ptr_inplace<MDIWindowButton, std::allocator<MDIWindowButton>, (__gnu_cxx::_Lock_policy)2>'
warning: RTTI symbol not found for class 'std::_Sp_counted_ptr_inplace<MDIWindowButton, std::allocator<MDIWindowButton>, (__gnu_cxx::_Lock_policy)2>'
std::shared_ptr<MDIWindowButton> (use count 1, weak count 0) = {get() = 0x55555557b510}
(gdb) print state
$5 = {id = 2, type = FL_UP_BOX, enabled = true}
(gdb) print buttons[1]
$6 = <error reading variable: Cannot access memory at address 0x219>
#include "base.h"
#include <FL/fl_draw.H>
#include "application.h"
MainApplication app;
int32_t MainApplication::menuHeight = 28;
int32_t MainApplication::border = 5;
uint8_t MainApplication::background = 125;
MainApplication::MainApplication(const char* caption)
: Fl_Double_Window(640, 480, caption)
, menubar( 0, 0, 480, menuHeight)
, workspace( 0, menuHeight, 638, 480 - menuHeight, "")
{
menubar.box(FL_FLAT_BOX);
menubar.menu(menu);
workspace.color(fl_rgb_color(background, background, background));
workspace.box(FL_DOWN_BOX);
workspace.align(Fl_Align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE));
workspace.labelcolor((Fl_Color) 0);
resizable(this);
resizable(workspace);
show();
}
int MainApplication::handle( int event_id ) {
int result = 0, current = 0;
const Fl_Cursor cursorType[] = {
FL_CURSOR_DEFAULT,
FL_CURSOR_NWSE,
FL_CURSOR_WE,
FL_CURSOR_NESW,
FL_CURSOR_NESW,
FL_CURSOR_WE,
FL_CURSOR_NWSE,
FL_CURSOR_NWSE,
FL_CURSOR_NS,
FL_CURSOR_NESW
};
switch( event_id ) {
case FL_MOVE:
if (Fl::event_x() >= 0 && (Fl::event_x() <= border)) {
current = 1;
if (Fl::event_y() >= border && (Fl::event_y() <= h() - border)) {
current += 1;
}
else {
current += 2;
}
}
else if (Fl::event_x() >= w() - border && (Fl::event_x() <= w())) {
current = 4;
if (Fl::event_y() >= border && (Fl::event_y() <= h() - border)) {
current += 1;
}
else {
current += 2;
}
}
else if (Fl::event_y() >= h() - border && (Fl::event_y() <= h())) {
current = 7;
if (Fl::event_x() >= x() + border && (Fl::event_x() <= w() - border)) {
current += 1;
}
else {
current += 2;
}
}
cursor(cursorType[current]);
break;
default:
result = Fl_Double_Window::handle( event_id );
break;
}
return result;
}
void MainApplication::resize(int x, int y, int width, int height) {
workspace.resize( border + 1, menuHeight, w() - (border * 2), h() - (menuHeight + border + 1));
menubar.resize( 0, 0, w(), menuHeight);
Fl_Double_Window::resize(x, y, width, height);
}
Fl_Menu_Item MainApplication::menu[] = {
{ "&File", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 0, 14, 0 },
{ "&Edit", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 0, 14, 0 },
{ "&Window", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 0, 14, 0 },
{ "&Help", 0, 0, 0, 0, (uchar)FL_NORMAL_LABEL, 0, 14, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
int main() {
return Fl::run();
}
#include "child.h"
class MainApplication: public Fl_Double_Window {
Fl_Menu_Bar menubar;
Fl_Scroll workspace;
static Fl_Menu_Item menu[];
static int32_t menuHeight, border;
static uint8_t background;
std::vector<MDIChildWindow*> children;
friend class MDIChildWindow;
MDIChildWindow *form = new MDIChildWindow( *this, 12, 50, 250, 100 );
public:
MainApplication(const char* caption = "Application Window");
virtual void resize(int x, int y, int width, int height);
virtual int handle( int event_id );
};
#include "base.h"
#include "application.h"
#define GENERIC_MAX(x, y) ((x) > (y) ? (x): (y))
#define ENSURE_int(i) _Generic((i), int: (i))
#define ENSURE_long(i) _Generic((i), unsigned long: (i))
#define MAX(type, x, y) (type) \
GENERIC_MAX(ENSURE_##type(x), ENSURE_##type(y))
static inline bool IntersectsRect (int x, int y, int width, int height, int pX, int pY) {
return ((pX > x and pX < (x + height ))
and (pY > y and pY < (y + width )));
}
size_t MDIWindowButton::szDefButtonSize = 16;
size_t MDIWindowButton::szDefPaddingSize = 2;
/* Not implemented, see below. */
MDIWindowButton::MDIWindowButton( MDIWindowDecor* mdiChildFrame )
: MDIWindowButton(mdiChildFrame, szDefButtonSize, szDefButtonSize, szDefPaddingSize ){}
/* Not implemented, see below. */
MDIWindowButton::MDIWindowButton( MDIWindowDecor* mdiChildFrame, int padding )
: MDIWindowButton(mdiChildFrame, szDefButtonSize, szDefButtonSize, padding ){}
MDIWindowButton::MDIWindowButton( MDIWindowDecor* form, int width, int height, int padding )
: control(form)
, bgColor(fl_rgb_color( 200, 200, 200 ))
{
std::vector<MDIWindowDecor::MDIWindowButtonT>& buttons((* control).buttons);
state.id = buttons.size() + 1;
metrics.padding = padding;
size_t pl = padding > 0?
(buttons.size() + 1) == 1? padding: (padding * buttons.size()) + ((padding * buttons.size()) / 2):
(szDefPaddingSize * 5) - (szDefPaddingSize / 2);
metrics.x = form->w() - (((width * buttons.size()) + padding + width ) + ( pl - (( padding > 1? padding: 6 ) / 2 )));
metrics.y = padding > 0? padding: szDefPaddingSize;
metrics.x -= padding;
printf("height is %zu\n", height);
if (buttons.size() > 0) {
size_t prevBtnId = buttons.size();
MDIWindowDecor::MDIWindowButtonT& previous = buttons[prevBtnId];
printf("(x = %d, y = %d) Adjust? Previous btnId = %zu\n", previous->metrics.x, previous->metrics.y, prevBtnId);
//
//metrics.x = previous.x();
//metrics.y = previous.y();
}
else {
puts("");
printf("ID = %d, Position = (%d, %d)\n", state.id, metrics.x, metrics.y);
puts("");
}
metrics.width = width + (padding > 0? padding: szDefPaddingSize);
metrics.height = height + (padding > 0? padding: szDefPaddingSize);
}
bool MDIWindowButton::handle( int event_id, size_t cx, size_t cy ) {
bool handled = false;
std::vector<MDIWindowDecor::MDIWindowButtonT>& buttons((* control).buttons);
if ( event_id == FL_PUSH ) {
if (IntersectsRect(x(), y(), height(), width(), cx, cy )) {
puts("I think this intersects?");
}
else {
printf("Click Event (%d, %d) occurred outside known button rectangle ((%d, %d) -> (%d, %d)).\n",
cx + (szDefPaddingSize * 4), cy, x(), y(), x() + width(), y() + height());
}
}
/*
if (btnRelX >= 0 && cy >= y() && btnRelX <= width() && cy <= height()) {
if (event_id == FL_PUSH || event_id == FL_RELEASE) {
for (MDIWindowButton& button : control.buttons ) {
if (button.state.id != state.id) {
button.state.type = FL_UP_BOX;
}
}
state.type = event_id == FL_PUSH? FL_DOWN_BOX: FL_UP_BOX;
handled = true;
}
}
else if (event_id == FL_RELEASE) {
state.type = FL_UP_BOX;
handled = true;
}
*/
return handled;
}
Fl_Boxtype MDIWindowButton::frame() { return state.type; }
Fl_Color MDIWindowButton::color() { return bgColor; }
size_t MDIWindowButton::id() { return state.id; }
size_t MDIWindowButton::x() { return metrics.x; }
size_t MDIWindowButton::y() { return metrics.y; }
size_t MDIWindowButton::width() { return metrics.width; }
size_t MDIWindowButton::height() { return metrics.height; }
class MainApplication;
class MDIChildWindow;
class MDIWindowDecor;
class MDIWindowButton {
public:
struct Rect { size_t x, y, height, width, padding; };
struct State { size_t id; Fl_Boxtype type; bool enabled; };
private:
Rect metrics = { 0, 0, 0, 0, 0 };
State state = { 0, FL_UP_BOX, true };
MDIWindowDecor* control;
Fl_Color bgColor;
static size_t szDefButtonSize, szDefPaddingSize;
public:
MDIWindowButton( MDIWindowDecor* control );
MDIWindowButton( MDIWindowDecor* control, int padding );
MDIWindowButton( MDIWindowDecor* control, int width, int height, int padding );
bool handle( int event_id, size_t x, size_t y );
size_t id();
Fl_Boxtype frame();
Fl_Color color();
size_t x();
size_t y();
size_t width();
size_t height();
};
class MDIWindowDecor: public Fl_Box {
MDIChildWindow& window;
friend class MDIWindowButton;
typedef std::shared_ptr<MDIWindowButton> MDIWindowButtonT;
bool handleMotion = false;
uint32_t originX, originY;
std::vector<MDIWindowButtonT> buttons;
MDIWindowButtonT button;
int handle( int event_id );
public:
MDIWindowDecor(MDIChildWindow& parent, const char* caption);
virtual void draw();
};
class MDIChildWindow: public Fl_Group {
MDIWindowDecor titlebar;
Fl_Group clientArea;
MainApplication& parent;
friend class MDIWindowDecor;
void draw();
void initialize();
public:
MDIChildWindow(MainApplication& parent, int offsetX, int offsetY, int w, int h );
};
#include "base.h"
#include "application.h"
static const uint32_t titleHeight = 26;
static const uint32_t padding = 5;
#define GENERIC_MAX(x, y) ((x) > (y) ? (x): (y))
#define ENSURE_int(i) _Generic((i), int: (i))
#define MAX(type, x, y) (type) \
GENERIC_MAX(ENSURE_##type(x), ENSURE_##type(y))
MDIWindowDecor::MDIWindowDecor(MDIChildWindow& parent, const char* caption)
: Fl_Box(parent.x() + ::padding, parent.y() + ::padding, parent.w() - (::padding * 2), titleHeight - ::padding, caption)
, window(parent)
{
buttons.push_back(std::make_shared<MDIWindowButton>( this ));
buttons.push_back(std::make_shared<MDIWindowButton>( this ));
buttons.push_back(std::make_shared<MDIWindowButton>( this, 0 ));
}
int MDIWindowDecor::handle( int event_id ) {
int result = 0;
switch (event_id) {
case FL_PUSH:
case FL_RELEASE: {
originX = window.x() - Fl::event_x();
originY = window.y() - Fl::event_y();
bool handled = false;
switch (event_id) {
case FL_PUSH:
for (std::shared_ptr<MDIWindowButton>& childBtn : buttons ) {
bool wasHandled = childBtn->handle( event_id, Fl::event_x(), Fl::event_y());
if (wasHandled) {
handled = wasHandled;
button = childBtn;
}
}
if (handled == false) {
handleMotion = event_id == FL_PUSH;
}
// A button indicated that it wished for the screen to be redrawn.
else {
redraw();
}
break;
case FL_RELEASE:
if (button != nullptr) {
button->handle( event_id, 0, 0 );
}
break;
}
result = 1;
} break;
case FL_DRAG:
if (handleMotion) {
switch (Fl::event_button()) {
case 1:
window.position(originX+Fl::event_x(), originY+Fl::event_y());
window.parent.redraw();
break;
}
}
result = 1;
break;
default:
result = Fl_Box::handle( event_id );
break;
}
return result;
}
void MDIWindowDecor::draw() {
Fl_Box::draw();
for (std::shared_ptr<MDIWindowButton>& button : buttons ) {
fl_draw_box( button->frame(), x() + button->x(), y() + button->y(), button->width(), button->height(), button->color());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment